📜  烧瓶 sqlalchemy.提交不保存更改 - SQL (1)

📅  最后修改于: 2023-12-03 15:40:48.539000             🧑  作者: Mango

烧瓶 SQLAlchemy 提交不保存更改 - SQL

简介

本文将介绍在使用烧瓶(Flask)和 SQLAlchemy 进行开发时遇到的提交不保存更改的问题,并提供解决方案。

问题描述

在使用 SQLAlchemy 进行数据库操作时,常常需要使用 session.commit() 方法将更改提交到数据库中。然而,在烧瓶中进行开发时,如果在提交前调用了 session.close() 方法关闭了会话对象,那么提交的更改不会保存到数据库中,这是因为 session.close() 方法会自动回滚事务。

这种情况可能会出现在使用 Flask 的 before_request 钩子函数中进行数据库操作时,因为在请求结束后 Flask 会将会话对象关闭。

解决方案

要解决这个问题,只需要在 app.teardown_appcontext 钩子函数中先判断会话对象是否发生了更改,如果发生了更改,则再提交更改:

from flask import Flask, g
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

# 在 Flask 应用关闭后运行函数
@app.teardown_appcontext
def close_db(error):
    # 从全局对象 g 中获取会话对象
    db = g.pop('db', None)
    if db is not None:
        # 判断是否发生了更改
        if db.session.transaction:
            # 提交更改
            db.session.commit()
        # 关闭会话对象
        db.session.close()

@app.before_request
def before_request():
    g.db = SQLAlchemy(app)

# 进行数据库操作
@app.route('/', methods=['GET', 'POST'])
def index():
    # 从全局对象 g 中获取会话对象
    db = g.get('db')
    # 进行数据库操作
    db.session.query(User).all()
    return 'Hello World!'

app.teardown_appcontext 钩子函数中,从全局对象 g 中获取会话对象 db.session ,然后判断是否发生了更改。如果发生了更改,则调用会话对象的 commit() 方法提交更改。最后调用会话对象的 close() 方法关闭会话对象。

总结

通过以上的解决方案,我们可以解决烧瓶 SQLAlchemy 提交不保存更改的问题,保证数据完整性。