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
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)).first()
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()
我有这段代码。我替换了
#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:
Now I am getting the following error.
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'
^CINFO:core:Going down...
以上代码用于处理count查询。为什么现在使用exists query。
答案 0 :(得分:1)
正如弗朗西斯 - 阿维拉在他精彩的answer to your other question中解释的那样,exists()...scalar() is not None
的逻辑存在问题。它返回True或False - 因此它总是返回None。对不起,我昨天建议如何在SQLAlchemy中使用exists,这是我的错误。
其他说明您的代码是正确的,并且在更改使用exists()
查询结果的逻辑后应该可以正常工作:
if session.query(exists().where(SourcetoPort.src_address == str(packet.dst))).scalar() is not None:
到
if session.query(exists().where(SourcetoPort.src_address == str(packet.dst))).scalar():
使用exists()... one()描述here的方法,处理异常也可以。请记住,在python中处理异常总是更昂贵的操作(使用更多的cpu周期)然后只是进行条件检查。如果您的应用程序不是性能关键 - 使用try / catch异常处理就可以了。