foos を更新する方法がないことがわかっている場合、なぜ を発行する必要があるdb.session.commit()
のでしょうか? 場合によっては、何かが更新された場合にのみコミットをトリガーするロジックを入れます。
foos = Foo.query.all()
行の下にa を追加するだけdb.session.commit()
です。これにより、行ごとに 1 つではなく、すべてのデータに対して 1 つのクエリが起動されます。
あなたが言うように、データをコミットすると期限切れに設定されるため、再クエリが必要になります。おそらく、再クエリするのではなく、セッションを更新することができますsession.refresh(object)
.
更新: 2 つのセッションの使用
2 番目のセッションを使用して をクエリし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() のもう 1 つの動作は、デフォルトでは、コミットが完了した後に存在するすべてのインスタンスの状態が期限切れになることです。これは、インスタンスが次にアクセスされたときに、属性アクセスまたはクエリ結果セットに存在することによってアクセスされるようにするためです。 、最新の状態を受け取ります。この動作を無効にするには、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)