query from sqlalchemy returns AttributeError: 'NoneType' object

karthik.sharma at gmail.com karthik.sharma at gmail.com
Thu May 2 18:14:22 EDT 2013


from pox.core import core
    import pox.openflow.libopenflow_01 as of
    import re
    import datetime
    
    from sqlalchemy import create_engine, ForeignKey
    from sqlalchemy import Column, Date, Integer, String
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import relationship, backref
    from sqlalchemy import create_engine
    from sqlalchemy.orm import sessionmaker
    from 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 this table to keep track of which ethernet address is on
        # which switch port (keys are MACs, values are ports).
        self.mac_to_port = {} 
        self.matrix={} 
    	
        #This will keep track of the traffic matrix. 
        #matrix[i][j]=number of times a packet from i went to j
      
      def send_packet (self, buffer_id, raw_data, out_port, in_port):
        #print "calling send_packet"
        #Sends a packet out of the specified switch port.
        msg = of.ofp_packet_out()
        msg.in_port = in_port
        msg.data = raw_data
        # Add an action to send to the specified port
        action = of.ofp_action_output(port = out_port)
        msg.actions.append(action)
        # Send message to switch
        self.connection.send(msg)
    
      def act_like_hub (self, packet, packet_in):
        #flood packet on all 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 the port for the source MAC
        #print "RECIEVED FROM PORT ",packet_in.in_port , "SOURCE ",packet.src
        # create a 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 for 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() is not None:
          	   #send this packet
    	   print "got info from the 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 a flow modification message
          	   msg = of.ofp_flow_mod()
          	   #set the fields to match from the incoming packet
    	   msg.match = of.ofp_match.from_packet(packet)
               #send the rule to the switch so that it does not query the controller again.
               msg.actions.append(of.ofp_action_output(port=q_res.port_no))
               #push the rule
               self.connection.send(msg)
        else:
               #flood this packet out as we don't know about this node.
               print "flooding the 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 the record to the session object
               session.add(entry)
               #add the record to the session object
               session.commit()
    
      def _handle_PacketIn (self, event):
        """
        Handles packet in messages from the switch.
        """
        packet = event.parsed # This is the parsed packet data.
        if not packet.parsed:
          log.warning("Ignoring incomplete packet")
          return
        packet_in = event.ofp # The actual ofp_packet_in message.
    
        #self.act_like_hub(packet, packet_in)
        self.act_like_switch(packet, packet_in)
    
    def launch ():
      """
      Starts the component
      """
      def start_switch (event):
        log.debug("Controlling %s" % (event.connection,))
        Tutorial(event.connection)
      core.openflow.addListenerByName("ConnectionUp", start_switch)



When I run the above code I get the following error:



The problem that I am facing is for some reason if I use 

    if session.query(exists().where(SourcetoPort.src_address == str(packet.dst))).scalar() is not None:

    in place of count query.

    #if session.query(SourcetoPort).filter_by(src_address=str(packet.dst)).count():

The querying from the 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 the 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 is Linux-3.5.0-23-generic-x86_64-with-Ubuntu-12.04-precise
    INFO:core:POX 0.1.0 (betta) is 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 from the 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 from the database
    ERROR:core:Exception while handling Connection!PacketIn...



More information about the Python-list mailing list