0

私は python と sqlalchemy にまったく慣れていません。次のネットワーク プログラムを作成しました。

class SourcetoPort(Base):
    """"""
    __tablename__ = 'source_to_port'
    id = Column(Integer, primary_key=True)
    port_no        = Column(Integer)
    src_address    = Column(String)

    #----------------------------------------------------------------------
    def __init__(self, src_address,port_no):
        """"""
        self.src_address = src_address
        self.port_no     = port_no
#
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
    Session = sessionmaker(bind=engine)
    session = Session()
    self.mac_to_port[packet.src]=packet_in.in_port
    if(self.matrix.get((packet.src,packet.dst))==None):
            # create a Session
            #print "creating a db session"
            #Session = sessionmaker(bind=engine)
            #session = Session()        
            self.matrix[(packet.src,packet.dst)]=0
            # Create an entry with address and port
            print "creating a new db entry"
            entry = SourcetoPort(src_address="packet.src" , port_no=packet_in.in_port)
            # Add the record to the session object
            session.add(entry)
            session.commit()
    self.matrix[(packet.src,packet.dst)]+=1
    #if self.mac_to_port.get(packet.dst)!=None:
    if session.query(SourcetoPort).filter_by(src_address=packet.dst).all():
      #send this packet
      self.send_packet(packet_in.buffer_id, packet_in.data,self.mac_to_port[packet.dst], 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)

      #print "SENDING  TO PORT " + str(self.mac_to_port[packet.dst]), packet.dst
      # send the rule to the switch so that it does not query the controller again.
      msg.actions.append(of.ofp_action_output(port=self.mac_to_port[packet.dst]))
      # push the rule
      self.connection.send(msg)

    else:
      #print 'flooding the packet '
      # Flood this packet out as we don't know about this node.
      self.send_packet(packet_in.buffer_id, packet_in.data,
                       of.OFPP_FLOOD, packet_in.in_port)

上記のコードの行

if session.query(SourcetoPort).filter_by(src_address='packet.dst').all():

期待どおりに動作しません。sqlalchemy データベースからエントリを取得し、成功した場合 (出力が NONE ではないため)、次のコードを実行する必要があることを期待しています。

print を使用してその行を印刷しようとすると

 print "session query", session.query(SourcetoPort).filter_by(src_address='packet.dst').all()

私が得る出力は

session query  []

誰かがこれを指摘できれば素晴らしいことです。

提案に基づいて上記の行を次のように変更すると、

print session.query(SourcetoPort).filter_by(src_address=packet.dst).count()

次のエラーが表示されます。

creating a new db entry
RECIEVED FROM PORT  2 SOURCE  96:74:ba:a9:92:b9
creating a new db entry

ERROR:core:Exception while handling Connection!PacketIn...
Traceback (most recent call last):
  File "ws_thesis/pox/pox/lib/revent/revent.py", line 234, in raiseEventNoErrors
    return self.raiseEvent(event, *args, **kw)
  File "ws_thesis/pox/pox/lib/revent/revent.py", line 281, in raiseEvent
    rv = event._invoke(handler, *args, **kw)
  File "ws_thesis/pox/pox/lib/revent/revent.py", line 159, in _invoke
    return handler(self, *args, **kw)
  File "ws_thesis/pox/tutorial.py", line 137, in _handle_PacketIn
    self.act_like_switch(packet, packet_in)
  File "ws_thesis/pox/tutorial.py", line 101, in act_like_switch
    print session.query(SourcetoPort).filter_by(src_address=packet.dst).count()
  File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2400, in count
    return self.from_self(col).scalar()
  File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2045, in scalar
    ret = self.one()
  File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2014, in one
    ret = list(self)
  File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2057, in __iter__
    return self._execute_and_instances(context)
  File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2072, in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
  File "/usr/lib/python2.7/dist-packages/sqlalchemy/engine/base.py", line 1405, in execute
4

1 に答える 1

2

変数の内容でアイテムをフィルタリングする場合は、その変数を直接使用する必要があります。

session.query(SourcetoPort).filter_by(src_address=packet.dst)

代わりに、文字列でフィルタリングしようとしていました'packet.dst'

エントリを作成するときに同じ間違いを犯しました。おそらく、文字列ではなく、式SourcetoPortの結果を保存したいでしょう:packet.src'packet.src'

SourcetoPort(src_address=packet.src, port_no=packet_in.in_port)

を呼び出すと、一致するすべてのエントリがデータベースから取得されますが、テスト.all()でのみ使用していることに注意してください。データベースに一致するアイテムの数を教えてもらう代わりに使用するif方が効率的です (潜在的にはるかに効率的です)。.count().all()

if session.query(SourcetoPort).filter_by(src_address=packet.dst).count():
于 2013-04-14T21:33:24.267 に答える