如果查询返回操作错误,如果用户无法访问数据库或类似的内容,如何强制我的引擎重新连接?
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?
答案 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()