python - SQLAlchemy:flush()とcommit()の違いは何ですか?


SQLAlchemyのflush()commit()の違いは何ですか?

私はドキュメントを読んだことがありますが、賢明な人はいません - 私は持っていないことを事前に理解しているようです。

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

私はあまりにも多くのcommit()と十分なflush()呼び出しを使用していないのだろうかと思っていますが、違いが何であるかを実際に理解することなく、伝えるのは難しいです!



Answers



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

セッションオブジェクトはトランザクション操作をsession.add()で登録しますが、 session.flush()が呼び出されるまでデータベースとの通信はまだ行いません。

session.flush()は一連の操作をデータベースに伝えます(挿入、更新、削除)。 データベースは、それらを保留中の操作としてトランザクション内に保持します。 変更はディスクに永続的に永続化されず、データベースが現在のトランザクション(これはsession.commit()と同じ)に対してCOMMITを受け取るまで表示されません。

session.commit()は、データベースに対する変更をコミットします(持続します)。

flush()常に commit()1 )の呼び出しの一部として呼び出されます。

セッションオブジェクトを使用してデータベースにクエリを実行すると、クエリは、データベースと保持しているコミットされていないトランザクションのフラッシュされた部分の両方から結果を返します。 デフォルトでは、セッションオブジェクトは操作を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')>]



@スナップショーによると

flush() SQL文をデータベースに送ります

commit()はトランザクションをコミットします。

session.autocommit == Falseの場合:

autoflush == Trueの場合、commit()はflush()を呼び出します。

session.autocommit == Trueの場合:

トランザクションを開始していない場合はcommit()を呼び出すことはできません(トランザクションを手動で管理することを避けるためにおそらくこのモードを使用しているためではないでしょう)。

このモードでは、flush()を呼び出してORMの変更を保存する必要があります。 また、フラッシュは効果的にデータをコミットします。