我让SQLAlchemy通过PGPool连接到Postgres。 PGPool配置为回收大约60年前的连接。
我有两个问题:
1)有时,我们会得到一个超过60秒的巨大查询(我知道它很糟糕......我们正在努力改进这一点),后续查询失败,因为它们依赖于不再有效的相同旧连接
2)同样,当我使用iPython启动我的Pyramid应用程序时,当我停下来思考片刻时,连接会变得陈旧。
当尝试使用陈旧连接的会话执行查询时,我得到一个例外:
OperationalError: (psycopg2.OperationalError) connection terminated due to client idle limit reached
ERROR: connection terminated due to client idle limit reached
SQLAlchemy的悲观断开处理文档建议在将其从池中取出时测试连接。但是,在签出后,连接变得陈旧,所以这没什么用。
我认为正确的解决方案是在遇到此类错误时刷新会话的连接:
session = MySession() # using scoped_session here
query = session.query(...)
try:
rows = [r for r in query]
except OperationalError:
# somehow tell query.session to use a new connection here and try again?
我该怎么做?
答案 0 :(得分:2)
对我来说,执行
session.close_all()
使会话能够运行查询,至少直到它再次闲置为止。
有趣的是,像SQLAlchemy documentation一样运行session.remove()
或session.close()
似乎意味着应该有效,但不起作用;这使得将来的查询会在调用InvalidRequestError: Can't reconnect until invalid transaction is rolled back
之前提供session.rollback()
(当然session.close_all()
无法修复)。
我希望有人能够深入了解为什么 session.close_all()
可以做到这一点,而且它可能不适合制作,但至少应该这样做,这样你就不会这样做。 ; t必须在iPython会话中重启整个应用程序。