1
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炼金术和东西很陌生。上面的代码是网络控制器的相关部分。只要有新的数据包进来,上面的代码就会被调用。我的问题是

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

这是知道 src_address 是否已经在数据库中的正确/最有效的方法吗?有人可以建议一些更好的方法吗?依靠正数似乎不太死板。

4

1 回答 1

1

情侣建议

1) 确保您的表在 src_address 字段上创建了索引。如果您使用 SQLAlchemy 创建模式索引,则可以通过对表定义的这个简单更改来添加。(参见使用元数据描述数据库:SQLAlchemy 手册的索引部分

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)我不确定你通过编写这个脚本来解决什么任务。我只是希望你不要每次新的网络数据包到达网络接口时都启动新的 python 脚本。启动新的 python 解释器进程需要几秒钟,每秒可能有数千个数据包到达。在后一种情况下,我会考虑将此类网络控制器程序作为守护程序运行,并将所有信息缓存在内存中。此外,我将实现数据库操作以在单独的线程甚至线程池中异步运行,因此它们不会阻塞控制网络流的主线程。

于 2013-05-02T15:13:57.827 回答