- 当插入一条新的记录时,使用
db.session.commit()
提交数据后,使用model.query()
查不到新增加的数据
db.session.commit()
是提交了数据到数据库,但是没有刷新模型映射中的数据,也就是model.query()
中的数据。而使用db.session.query()
则是 从整个服务会话中进行查询,而db.session.commit()
提交的数据在这里是有刷新的。
以上是我在网上找到的答案,当时也是遇到这个问题,增或者改数据后,直接model.query的结果时对时错,换成db.session这种模式就没问题了,我用的是flask-sqlalchemy库。
所以我有两个问题,第一个是导致这种情况发生的是如同上述吗?第二个,如果真的是存在这种情况,为什么很多教程包括辉大佬你的flask项目都还是model.query形式?
参考链接:
greyli
(Grey Li)
4
test2 里第二次查询赋值的变量是 books1
,而你打印出来的是 books
。
以后麻烦用纯文本给出代码,你这样别人没法在本地运行测试。
class Book(PkModel):
"""books for a user."""
__tablename__ = "books"
name = Column(db.String(80), nullable=False)
user_id = Column(db.Integer)
def __init__(self, name, **kwargs):
"""Create instance."""
super().__init__(name=name, **kwargs)
def __repr__(self):
"""Represent instance as a unique string."""
return f"<Book({self.name})>"
@blueprint.route("/test1/<name>", methods=["GET", "POST"])
def test1(name):
db.session.add(Book(name=name))
db.session.commit()
print(f"新增book:{name}")
return jsonify({"msg": "ok"})
@blueprint.route("/test2", methods=["GET", "POST"])
def test2():
books = [i.name for i in Book.query.all()]
print(f"第一次查询:{books}")
time.sleep(10)
books1 = [i.name for i in Book.query.all()]
print(f"第二次查询:{books1}")
return jsonify({"msg": "ok", "books": books, "book1": books1})
先请求一次test2 查询 ,然后再紧接着请求test1插入数据,发现test2请求的2次结果不变
from sqlalchemy import create_engine
engine = create_engine("mysql://scott:tiger@hostname/dbname",
encoding='utf-8', isolation_level='READ COMMITTED')
stackflow上有的回答是设置隔离级别为read-committed就可以,但是flask-sqlalchemy怎么设置隔离级别?我找不到这个方法或者参数。
greyli
(Grey Li)
9
使用 SQLALCHEMY_ENGINE_OPTIONS
配置,传递一个字典,键值匹配传入 create_engine
的参数。另外 SQLAlchemy
类也可以传递一个 engine_options
字典,作用相同,但是会覆盖对应配置的值。
swpo
(shenw)
11
这是数据库隔离级别的问题,MySQL默认隔离级别是可重复读(REPEATABLE-READ),所以同一个事务里面前后查询结果是相同的;建议您第一次查询后显示提交或回滚事务,然后进行第二次查询。
那怎么解决这个问题,sqlalchemy不能实时读取到最新的数据,手动设置隔离级别?
swpo
(shenw)
14
个人不建议手动改隔离级别,建议分多次请求查询,或者查询后显示提交事务吧。
那还是用model.query形式? 还是用db.session.query(model) ?