python - query from sqlalchemy returns AttributeError: 'NoneType' object -


from pox.core import core import pox.openflow.libopenflow_01 of import re import datetime  sqlalchemy import create_engine, foreignkey sqlalchemy import column, date, integer, string sqlalchemy.ext.declarative import declarative_base sqlalchemy.orm import relationship, backref sqlalchemy import create_engine sqlalchemy.orm import sessionmaker sqlalchemy.sql.expression import exists  log = core.getlogger()  engine = create_engine('sqlite:///nwtopology.db', echo=false) base = declarative_base() session = sessionmaker(bind=engine) session = session()  ######################################################################## class sourcetoport(base):     """"""     __tablename__ = 'source_to_port'     id = column(integer, primary_key=true)     port_no        = column(integer)     src_address    = column(string,index=true)      #----------------------------------------------------------------------     def __init__(self, src_address,port_no):         """"""         self.src_address = src_address         self.port_no     = port_no  ########################################################################  #create tables base.metadata.create_all(engine)  class tutorial (object):   def __init__ (self, connection):     self.connection = connection     connection.addlisteners(self)     # use table keep track of ethernet address on     # switch port (keys macs, values ports).     self.mac_to_port = {}      self.matrix={}       #this keep track of traffic matrix.      #matrix[i][j]=number of times packet went j    def send_packet (self, buffer_id, raw_data, out_port, in_port):     #print "calling send_packet"     #sends packet out of specified switch port.     msg = of.ofp_packet_out()     msg.in_port = in_port     msg.data = raw_data     # add action send specified port     action = of.ofp_action_output(port = out_port)     msg.actions.append(action)     # send message switch     self.connection.send(msg)    def act_like_hub (self, packet, packet_in):     #flood packet on ports     self.send_packet(packet_in.buffer_id, packet_in.data,                      of.ofpp_flood, packet_in.in_port)    def act_like_switch (self, packet, packet_in):     """     implement switch-like behavior.     """     # learn port source mac     #print "recieved port ",packet_in.in_port , "source ",packet.src     # create session     #session = sessionmaker(bind=engine)     #session = session()     self.mac_to_port[packet.src]=packet_in.in_port     #if self.mac_to_port.get(packet.dst)!=none:     #print "count dst",session.query(sourcetoport).filter_by(src_address=str(packet.dst)).count(),str(packet.dst)     #if session.query(sourcetoport).filter_by(src_address=str(packet.dst)).count():     if session.query(exists().where(sourcetoport.src_address == str(packet.dst))).scalar() not none:            #send packet        print "got info database"        q_res = session.query(sourcetoport).filter_by(src_address=str(packet.dst)).one()        self.send_packet(packet_in.buffer_id, packet_in.data,q_res.port_no, packet_in.in_port)            #create flow modification message            msg = of.ofp_flow_mod()            #set fields match incoming packet        msg.match = of.ofp_match.from_packet(packet)            #send rule switch not query controller again.            msg.actions.append(of.ofp_action_output(port=q_res.port_no))            #push rule            self.connection.send(msg)     else:            #flood packet out don't know node.            print "flooding first packet"            self.send_packet(packet_in.buffer_id, packet_in.data,                        of.ofpp_flood, packet_in.in_port)        #self.matrix[(packet.src,packet.dst)]+=1          entry = sourcetoport(src_address=str(packet.src) , port_no=packet_in.in_port)            #add record session object            session.add(entry)            #add record session object            session.commit()    def _handle_packetin (self, event):     """     handles packet in messages switch.     """     packet = event.parsed # parsed packet data.     if not packet.parsed:       log.warning("ignoring incomplete packet")       return     packet_in = event.ofp # actual ofp_packet_in message.      #self.act_like_hub(packet, packet_in)     self.act_like_switch(packet, packet_in)  def launch ():   """   starts component   """   def start_switch (event):     log.debug("controlling %s" % (event.connection,))     tutorial(event.connection)   core.openflow.addlistenerbyname("connectionup", start_switch) 

when run above code following error:

the problem facing reason if use

if session.query(exists().where(sourcetoport.src_address == str(packet.dst))).scalar() not none:  in place of count query.  #if session.query(sourcetoport).filter_by(src_address=str(packet.dst)).count(): 

the querying database

q_res = session.query(sourcetoport).filter_by(src_address=str(packet.dst)).first() self.send_packet(packet_in.buffer_id, packet_in.data,q_res.port_no, packet_in.in_port) 

is giving following error:

debug:core:pox 0.1.0 (betta) going up... debug:core:running on cpython (2.7.3/aug 1 2012 05:14:39) debug:core:platform linux-3.5.0-23-generic-x86_64-with-ubuntu-12.04-precise info:core:pox 0.1.0 (betta) up. debug:openflow.of_01:listening on 0.0.0.0:6633 info:openflow.of_01:[00-00-00-00-00-02 1] connected debug:tutorial:controlling [00-00-00-00-00-02 1] got info database error:core:exception while handling connection!packetin... traceback (most recent call last):   file "/home/karthik/pox/pox/lib/revent/revent.py", line 234, in raiseeventnoerrors     return self.raiseevent(event, *args, **kw)   file "/home/karthik/pox/pox/lib/revent/revent.py", line 281, in raiseevent     rv = event._invoke(handler, *args, **kw)   file "/home/karthik/pox/pox/lib/revent/revent.py", line 159, in _invoke     return handler(self, *args, **kw)   file "/home/karthik/pox/tutorial.py", line 118, in _handle_packetin     self.act_like_switch(packet, packet_in)   file "/home/karthik/pox/tutorial.py", line 86, in act_like_switch     self.send_packet(packet_in.buffer_id, packet_in.data,q_res.port_no, packet_in.in_port) attributeerror: 'nonetype' object has no attribute 'port_no' got info database error:core:exception while handling connection!packetin... 

this line:

if session.query(exists().where(sourcetoport.src_address == str(packet.dst))).scalar() not none: 

is true. reason scalar() returns none if there no rows. query looks select exists (select * source_to_port source_to_port.src_address=?). always return 1 row 1 column. result true or false, never none.

moving on line before line throws exception: first() returns none if there no matches, q_res none. since q_res none, q_res.port_no on next line raises exception.

(note can use one() if want exception thrown if there no match.)

if expecting match, double-check data , filter_by() condition make sure doing think should.

however recommend use 1 query instead of 2 using first() or one(). first(), branch based on q_res being none or not:

q_res = session.query(sourcetoport).filter_by(src_address=str(packet.dst)).first() if q_res not none:     print "got info database"     self.send_packet(....)     ... else:     print "flooding first packet"     ... 

or one(), put "flooding" branch in exception handler:

from sqlalchemy.orm.exc import (noresultfound, multipleresultsfound)  try:     q_res = session.query(sourcetoport).filter_by(src_address=str(packet.dst)).one() except noresultfound:     print "flooding first packet"     ... # except multipleresultsfound: #     print "more 1 result found! wut?!" else:     print "got info database"     ... 

a difference between these 2 approaches one() ensure there 1 and one result, whereas first() doesn't care if there multiple results.


Comments

Popular posts from this blog

linux - Does gcc have any options to add version info in ELF binary file? -

android - send complex objects as post php java -

charts - What graph/dashboard product is facebook using in Dashboard: PUE & WUE -