SQLAlchemy 会话重新连接

新手上路,请多包涵

如果查询返回 OperationalError,比如用户无权访问数据库或类似的东西,我如何强制我的引擎重新连接?

 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?

原文由 bwbrowning 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.4k
2 个回答

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

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

原文由 zzzeek 发布,翻译遵循 CC BY-SA 3.0 许可协议

自从第一次回答这个问题以来发生了很多事情。

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

创建引擎时应用 pool_pre_ping=True ,如下所示:

 engine = create_engine("mysql+pymysql://user:pw@host/db", pool_pre_ping=True)

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


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

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


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

原文由 chjortlund 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏