所以我有一个守护进程通过sqlalchemy与Postgres对话。守护进程做了这样的事情:
while True:
oEngine = setup_new_engine()
with oEngine.connect() as conn:
Logger.debug("connection established")
DBSession = sessionmaker(bind=conn)()
Logger.debug('DBSession created. id={0}'.format(id(DBSession)))
#do a bunch of stuff with DBSession
DBSession.commit()
Logger.debug('DBSession committed. id={0}'.format(id(DBSession)))
在永久循环的第一次迭代中,一切都很好。一阵子。 DBSession
成功地向数据库发出了一些查询。但是一个查询失败并出现错误:
OperationalError: (OperationalError) SSL SYSCALL error: Bad file descriptor
这告诉我使用了一个封闭的连接或文件描述符。但这些连接是由守护进程创建和维护的,所以我不知道这意味着什么。
换句话说,会发生什么:
create engine
open connection
setup dbsession
query dbsession => works great
query dbsession => ERROR
有问题的查询如下:
DBSession.query(Login)
.filter(Login.LFTime == oLineTime)
.filter(Login.success == self.success)
.count()
这对我来说似乎完全合情合理。
我的问题是:这种行为可能有什么样的原因,我该如何解决或隔离问题呢?
如果您需要更多代码,请与我们联系。有很多,所以我在这里采取极简主义的方法......
答案 0 :(得分:2)
我通过考虑会话范围而不是事务范围来解决这个问题。
while True:
do_stuff()
def do_stuff():
oEngine = setup_new_engine()
with oEngine.connect() as conn:
Logger.debug("connection established")
DBSession = sessionmaker(bind=conn)()
#do a bunch of stuff with DBSession
DBSession.commit()
DBSession.close()
我仍然想知道为什么这个固定的东西虽然......
答案 1 :(得分:1)
您正在while循环中创建会话,这是非常不明智的。使用第一次使用代码的方式,您将在每次迭代时生成一个新连接并保持打开状态。不久之后,您将受到某种限制并且无法打开另一个新会话。 (什么样的限制?很难说,但它可能是一个内存条件,因为数据库连接非常重;它可能是一个数据库服务器限制,它只会因性能原因接受一定数量的同时用户连接;很难知道并且它并不重要,因为无论限制是什么,它都会阻止您使用非常浪费的方法,因此已按预期工作!)
您遇到的解决方案可以解决问题,因为当您为每个循环打开一个新连接时,您也可以使用每个循环关闭它,释放资源并允许其他循环创建自己的会话并成功。但是,这仍然是服务器和客户端上的大量不必要的繁忙和浪费处理资源。如果你将sessionmaker
移到while
循环之外,我怀疑它会同样有效 - 并且可能很多更快。
def main():
oEngine = setup_new_engine()
with oEngine.connect() as conn:
Logger.debug("connection established")
DBSession = sessionmaker(bind=conn)()
apparently_infinite_loop(DBSession)
# close only after we are done and have somehow exited the infinite loop
DBSession.close()
def apparently_infinite_loop(DBSession):
while True:
#do a bunch of stuff with DBSession
DBSession.commit()
我目前没有工作的sqlalchemy设置,所以你可能会有一些语法错误,但无论如何我希望它能说明基本的根本问题。
此处提供了更多详细信息:http://docs.sqlalchemy.org/en/rel_0_9/orm/session.html#session-faq-whentocreate
文档中的一些要点: