engine = create_engine('sqlite:///nwtopology.db', echo=False)
Base = declarative_base()
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
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):
self.matrix[(packet.src,packet.dst)]=0
print "found a new flow"
#create an databse entry with address and port
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()
self.matrix[(packet.src,packet.dst)]+=1
print "incrementing flow count"
#if self.mac_to_port.get(packet.dst)!=None:
if session.query(SourcetoPort).filter_by(src_address=str(packet.dst)).count():
#do stuff if the flow information is already in the databaase.
我对 python 和 sql alchemy 等东西非常陌生。上面的代码是网络 Controller 的相关部分。每当有新数据包进入时,上面的代码就会被调用。我的问题是
if session.query(SourcetoPort).filter_by(src_address=str(packet.dst)).count():
这是了解 src_address 是否已在数据库中的正确/最有效的方法吗?有人可以建议一些更好的方法吗?依赖正数似乎不太严格。
最佳答案
一些建议
1) 确保您的表在 src_address 字段上创建了索引。如果您使用 SQLAlchemy 创建架构索引,则可以通过对表定义的简单更改来添加。 (更多信息请参见Describing Databases with MetaData: Indexes part of SQLAlchemy manual)
class SourcetoPort(Base):
""""""
__tablename__ = 'source_to_port'
id = Column(Integer, primary_key=True)
port_no = Column(Integer)
src_address = Column(String, index=True)
2) 要检查是否有 src_address=str(packet.dst) 的记录,还有另一种方法,即使用 EXISTS。因此,它不必扫描具有此类 src_address 的所有记录,而是在找到第一条具有此类字段值的记录时立即返回结果。
if session.query(SourcetoPort).filter_by(src_address=str(packet.dst)).count():
#do stuff if the flow information is already in the databaase.
用存在查询替换计数查询
from sqlalchemy.sql.expression import exists
if session.query(exists().where(SourcetoPort.src_address == '123')).scalar() is not None:
#do stuff if the flow information is already in the database.
3)我不确定您通过编写此脚本来解决什么任务。我只是希望你不会在每次新的网络数据包到达网络接口(interface)时启动新的 python 脚本。启动新的 python 解释器进程需要几秒钟的时间,并且每秒可能有数千个数据包到达。 在后一种情况下,我会考虑将此类网络 Controller 程序作为守护进程运行,并将所有信息缓存在内存中。此外,我还将实现数据库操作以在单独的线程甚至线程池中异步运行,因此它们不会阻止控制网络流的主线程。
关于python - 从 sqlalchemy 数据库查询数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16329790/