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

时间:2015-08-07 17:56:52

标签: python sqlalchemy connection-pooling pyramid

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

我该怎么做?

1 个答案:

答案 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会话中重启整个应用程序。