如果您知道 foos 无法更新,为什么还要发布db.session.commit()
呢?如果有时是这样,那么只有在某些内容已更新时才会在其中添加一些逻辑来触发提交。
您可以foos = Foo.query.all()
在该行下方添加一个db.session.commit()
。这将只对所有数据触发一个查询,而不是每行一个。
正如您所说,提交数据会将其设置为过期,因此需要重新查询它们。也许您可以刷新会话而不是重新查询,有关SQLAlchemy 文档中的更多信息似乎表明您可以这样做session.refresh(object)
。
更新:使用两个会话
您可以使用第二个会话,您将使用它来查询Foo
,然后另一个会话来处理Bars
. 当您提交时,这将使 foos 保持不变,因此您不必再次点击它。
这是一个粗略的例子:
from flask.ext.sqlalchemy import Session
@app.route('/example/')
def home():
session_two = Session(bind=db.engine.connect())
foos = session_two.query(Foo).all()
for foo in foos:
db.session.add(Bar(foo))
db.session.commit()
return render_template_string('''
{% for foo in foos %}
{{ foo.name }}
{% endfor %}
''', foos=foos)
expire_on_commit=False
另外,我想知道您是否可以通过文档中配置的单个会话来处理它:
“commit() 的另一个行为是,默认情况下,它会在提交完成后使存在的所有实例的状态过期。这是为了在下次访问实例时,通过属性访问或它们存在于查询结果集中, 他们收到最新的状态。要禁用此行为,请将 sessionmaker 配置为 expire_on_commit=False"
使用 Session.expunge
根据需要从会话中删除对象
@app.route('/')
def home():
foos = Foo.query.all()
for foo in foos:
db.session.add(Bar(foo))
db.session.expunge(foo)
db.session.commit()
return render_template_string('''
{% for foo in foos %}
{{ foo.name }}
{% endfor %}
''', foos=foos)