SQLAlchemy のflush()
との違いは何ですか?commit()
ドキュメントを読みましたが、何も分かりません。ドキュメントでは、私が持っていない事前の理解を前提としているようです。
私は特に、メモリ使用量への影響に興味があります。一連のファイルからデータベースにデータ (合計約 500 万行) をロードしているのですが、セッションが時々ダウンします。データベースが大きく、マシンのメモリがあまり多くないからです。
commit()
呼び出しが多すぎるのか、少なすぎるのか疑問に思っていますflush()
が、違いが何なのかを実際に理解していないと、判断が難しいです。
ベストアンサー1
セッション オブジェクトは、基本的に、データベースへの変更 (更新、挿入、削除) の進行中のトランザクションです。これらの操作は、コミットされるまでデータベースに保存されません (何らかの理由でセッションの途中でトランザクションが中止された場合、コミットされていない変更はすべて失われます)。
セッション オブジェクトは でトランザクション操作を登録しますが、が呼び出されるsession.add()
まではデータベースにそれらを伝達しません。session.flush()
session.flush()
一連の操作 (挿入、更新、削除) をデータベースに伝えます。データベースは、これらの操作をトランザクション内の保留中の操作として保持します。変更は、データベースが現在のトランザクションの COMMIT を受信するまで (これが実行されますsession.commit()
)、ディスクに永続的に保存されず、他のトランザクションにも表示されません。
session.commit()
これらの変更をデータベースにコミット (保存) します。
flush()
は常に(の呼び出しの一部として呼び出されますcommit()
)1)。
Session オブジェクトを使用してデータベースをクエリすると、クエリはデータベースからの結果と、データベースが保持するコミットされていないトランザクションのフラッシュされた部分からの結果の両方を返します。デフォルトでは、Session オブジェクトがautoflush
その操作を実行しますが、これを無効にすることもできます。
次の例でこれがより明確になると思います:
#---
s = Session()
s.add(Foo('A')) # The Foo('A') object has been added to the session.
# It has not been committed to the database yet,
# but is returned as part of a query.
print 1, s.query(Foo).all()
s.commit()
#---
s2 = Session()
s2.autoflush = False
s2.add(Foo('B'))
print 2, s2.query(Foo).all() # The Foo('B') object is *not* returned
# as part of this query because it hasn't
# been flushed yet.
s2.flush() # Now, Foo('B') is in the same state as
# Foo('A') was above.
print 3, s2.query(Foo).all()
s2.rollback() # Foo('B') has not been committed, and rolling
# back the session's transaction removes it
# from the session.
print 4, s2.query(Foo).all()
#---
Output:
1 [<Foo('A')>]
2 [<Foo('A')>]
3 [<Foo('A')>, <Foo('B')>]
4 [<Foo('A')>]