当连接失效时重新运行SQLAlchemy查询



我有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?

我该怎么做?

对于我来说,执行

session.close_all()

使会话能够运行查询,至少直到它再次空闲。

有趣的是,运行session.remove()session.close(),就像SQLAlchemy文档似乎暗示应该工作一样,没有工作;这使得未来的查询给InvalidRequestError: Can't reconnect until invalid transaction is rolled back(当然session.rollback()不修复),直到调用session.close_all()

我希望有人能提供洞察为什么 session.close_all()做到了这一点,它可能不是一个合适的解决方案用于生产,但至少应该使它,所以你不需要重新启动整个应用程序在你的iPython会话

最新更新