2013-04-14 40 views
0

我對python和sqlalchemy.I已經寫了下面的netowrk程序。python與sqlalchemy db retrogra

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(): 

如我所料it.What我希望不工作是,它應該從retrive數據庫SQLAlchemy的,如果它進入成功(因爲輸出不是NONE)它應該執行下面的代碼。

當我嘗試使用打印

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

,我得到的輸出打印該行是

session query [] 

我做得wrong.It將是巨大的,如果有人能指出這一點。

如果我改變基礎上,建議在上述行

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 
+0

我對於「==」索賠道歉,我糊塗了與關鍵字語法上的直接列參考語法。你的回溯仍然不完整。什麼*是'packet.dst'的值,並且與您的列兼容* –

回答

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():