1. ホーム
  2. python

[解決済み] SQLAlchemy: flush() と commit() の違いは何ですか?

2022-03-17 09:40:47

質問

とはどのような違いがあるのですか? flush()commit() をSQLAlchemyで作成することはできますか?

ドキュメントを読みましたが、よくわかりません。私が持っていない事前理解を前提としているようです。

特にメモリ使用量への影響に興味があります。私はいくつかのデータを一連のファイルからデータベースにロードしています(合計で約500万行)、そして私のセッションは時々落ちています。

を多用しすぎているのでは? commit() が足りず flush() を呼び出しますが、その違いが何なのかをよく理解していないと、伝えるのは難しいですね。

どのように解決するのか?

Session オブジェクトは基本的に、データベースへの変更 (更新、挿入、削除) の進行中のトランザクションです。これらの操作はコミットされるまでデータベースには残りません(セッション・トランザクションの途中で何らかの理由でプログラムが中断すると、コミットされていない変更は失われます)。

セッションオブジェクトは、トランザクション操作を 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')>]