简体   繁体   English

如果引发异常,如何使 Flask-SQLAlchemy 自动回滚会话?

[英]How to make Flask-SQLAlchemy automatically rollback the session if an exception is raised?

I'd like to setup an app built with Flask-SQLAlchemy to rollback all changes done to the database if the view raises an exception that bubbles outside the view code (ie not catched inside).我想设置一个使用Flask-SQLAlchemy构建的应用程序,以便在视图引发在视图代码之外冒泡的异常(即未捕获到内部)时回滚对数据库所做的所有更改。

I'd like it to work even if some objects are flushed to the database in subtransactions, either automatically or directly via session.commit() .即使某些对象在子事务中自动或直接通过session.commit()刷新到数据库,我也希望它能够工作。

Something similar to Django's transaction request wrapping .类似于Django 的事务请求包装

you can do something like this:你可以做这样的事情:

@app.teardown_request
def teardown_request(exception):
    if exception:
        db.session.rollback()
    db.session.remove()

Have a look here for teardown_request info. 在这里查看teardown_request 信息。 You might need to set the PRESERVE_CONTEXT_ON_EXCEPTION config variable if you are in debug mode.如果您处于调试模式,您可能需要设置PRESERVE_CONTEXT_ON_EXCEPTION配置变量。

You could include the rollback in a custom error handler...您可以在自定义错误处理程序中包含回滚...

@app.errorhandler(500)
def internal_error(error):
    db.session.rollback()
    return render_template('500.html'), 500

See here under the Custom Error Pages section.请参阅自定义错误页面部分下的此处

The most reliable solution that has worked for me, inspired by dduffy's answer , is to attach an errorhandler that specifically catches SQLAlchemy exceptions and issue a rollback.dduffy's answer启发,对我有用的最可靠的解决方案是附加一个专门捕获 SQLAlchemy 异常并发出回滚的错误处理程序。

from sqlalchemy import exc
@app.errorhandler(exc.SQLAlchemyError)
def handle_db_exceptions(error):
    #log the error: app.logger.error(error)
    db.session.rollback()

The @app.teardown_request hook approach didn't seem to fix the db connection that was in a bad state in time before it was reused by later requests pulling it from the db connection pool. @app.teardown_request钩子方法似乎没有及时修复处于错误状态的数据库连接,然后才被后来的请求从数据库连接池中拉出它。 The errorhandler approach catches the connection before it is reused, and by limiting it in scope to the class of errors raised by SQLAlchemy it feels more precise. errorhandler方法在重用之前捕获连接,并且通过将其范围限制为 SQLAlchemy 引发的错误类别,它感觉更精确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM