Son*_*Son 8 python orm sqlalchemy flask flask-sqlalchemy
我想知道SQLAlchemy如何跟踪SQLAlchemy之外的更改(例如手动更改)?
到目前为止,我曾经db.session.commit()在每个可以在SQLAlchemy之外更改的值之前放置.这是一种不好的做法吗?如果是的话,是否有更好的方法来确保我拥有最新价值?我实际上在下面创建了一个小脚本来检查它,显然,SQLAlchemy可以检测外部更改,而db.session.commit()不是每次调用.
谢谢,
PS:我真的想了解SQLAlchemy工作背后的所有魔法是如何发生的.有没有人指向一些文档解释SQLAlchemy的幕后工作?
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# Use SQLlite so this example can be run anywhere.
# On Mysql, the same behaviour is observed
basedir = os.path.abspath(os.path.dirname(__file__))
db_path = os.path.join(basedir, "app.db")
app.config["SQLALCHEMY_DATABASE_URI"] = 'sqlite:///' + db_path
db = SQLAlchemy(app)
# A small class to use in the test
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100))
# Create all the tables and a fake data
db.create_all()
user = User(name="old name")
db.session.add(user)
db.session.commit()
@app.route('/')
def index():
"""The scenario: the first request returns "old name" as expected.
Then, I modify the name of User:1 to "new name" directly on the database.
On the next request, "new name" will be returned.
My question is: how SQLAlchemy knows that the value has been changed?
"""
# Before, I always use db.session.commit()
# to make sure that the latest value is fetched.
# Without db.session.commit(),
# SQLAlchemy still can track change made on User.name
# print "refresh db"
# db.session.commit()
u = User.query.filter_by(id=1).first()
return u.name
app.run(debug=True)
Run Code Online (Sandbox Code Playgroud)
小智 5
会话的“缓存”是其identity_map(session.identity_map.dict)中的字典,仅在“单个业务交易”时缓存对象,如此处/sf/answers/410885681/所回答。
对于不同的服务器请求,您具有不同的identity_map。它不是共享对象。
在您的方案中,您请求服务器2个分开的时间。第二次,identity_map是一个新的(您可以通过打印出其指针轻松地对其进行检查),并且在缓存中没有任何内容。因此,该会话将请求数据库并为您提供更新的答案。它不会像您想的那样“跟踪变更”。
因此,对于您的问题,如果尚未在同一服务器请求中对同一对象进行查询,则无需在查询之前执行session.commit()。
希望能帮助到你。
| 归档时间: |
|
| 查看次数: |
1320 次 |
| 最近记录: |