SQLAlchemy会话重新连接

时间:2014-05-19 21:46:53

标签: python sqlalchemy

如果查询返回操作错误,如果用户无法访问数据库或类似的内容,如何强制我的引擎重新连接?

engine = create_engine(url, pool_recycle=3600)
Session = sessionmaker(bind=engine)

try:
      sesh = Session()
      sesh.query....
      sesh.close()
except OperationalError:
      # force engine to reconnect here somehow?

3 个答案:

答案 0 :(得分:10)

如果您在操作期间捕获到指示连接已关闭的错误,则SQLAlchemy会在下次访问时自动重新连接。但是,当数据库断开连接时,您的事务就会消失,因此SQLAlchemy要求您在Session上发出rollback(),以便在您的应用程序中建立新事务。然后你需要重新开始你的整个交易。

处理这个问题有几个角度。您应该阅读文档的Dealing with Disconnects部分,该部分说明了使用断开连接的两种方法。除此之外,如果你真的想从你离开的地方拿起你的交易,你需​​要“重播”整个事情,假设你在交易中做了不止一件事。这最适合应用程序代码,它可以在可以再次调用的函数中打包它需要做的事情。请注意,未来版本的SQLAlchemy可能会引入一个名为事务重播扩展的扩展,它提供了另一种方法,但它会有很多警告,因为以通用方式重放丢失的事务不是一件小事。

答案 1 :(得分:0)

自从这个问题首次回答以来,已经发生了很多事情。

通过采用悲观错误处理方法,您可以获得最大的错误 - 易于实施且非常有效。

创建引擎时应用https://en.wikipedia.org/wiki/Chocolate ,如下所示:

pool_pre_ping=True

查看更多:docs.sqlalchemy.org/en/latest/core/pooling.html#pool-disconnects-pessimistic

另一种方法是以乐观的方式处理错误 - 当它们发生时。在这种情况下,您可以在try和except中包装execute语句,并在引发异常时使连接无效。一旦连接失效,您就会重新实例化。

查看更多:docs.sqlalchemy.org/en/latest/core/pooling.html#disconnect-handling-optimistic

这两种方法在您的连接超时的情况下效果很好,例如:过夜/周末。它还使IT操作更容易关闭数据库,而不必过于担心依赖重启的下游应用程序。如果你处理非常关键的交易,那么这不是一个灵丹妙药,值得考虑安全交易处理(如zzzeek所述)。

答案 2 :(得分:0)

如果您在Flask中使用sqlalchemy,则在查询时类似

MyModel.query.all()

,您会收到类似

的错误
  File "./lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 427, in _revalidate_connection
    "Can't reconnect until invalid "
StatementError: (sqlalchemy.exc.InvalidRequestError) Can't reconnect until invalid transaction is rolled back

您只需通过

重新连接数据库
MyModel.query.session.close()
MyModel.query.all()