25
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SQLAlchemy flush(), commit()の違い

Last updated at Posted at 2020-10-29

PythonのO/R Mapper の1つであるSQLAlchemyを利用してテーブルのレコード操作する際に使用する flush(), commit()の使い分けについて説明します

最近、仕事で使うようになり少しずつ学習しています。

簡単に言葉で表現するなら
flush():一時的にクエリ結果をデータベースに反映(ロールバック可能なので、commit()しないとクエリが無効になり、最後にcommit()する必要あり)
commit():永続的にクエリの結果をデータベースに反映(レコードの追加、更新、削除の完了)

それぞれの用途としては
エラー時にロールバックして、データベースへの反映を無かったことにしたい場合に使うと便利なのがflush()

例えば、

session.begin()
try:
    for item in session.query(Model).all():
       session.add(Model)
       session.flush() # <-保留状態
    session.commit() # <-ここで永続的にデータベースへ反映
except:
   session.rollback() # 保留状態を破棄して、データベースへの反映は全くない
finally:
    session.close() # エラー発生&正常終了、どちらでもセッションを閉じる

逆にロールバックしたくない場合はcommit()を使います

session.begin()
try:
    for item in session.query(Model).all():
       session.add(Model)
       session.commit() # <-都度都度、永続的にデータベースへ反映
except Exception as e:
   print('Error:{}'.format(str(e)))
   raise e
finally:
    session.close() # エラー発生&正常終了、どちらでもセッションを閉じる

エラーが発生せず処理の最後でデータベースへ処理内容を反映させる場合にはcommit()を使います。

正式な説明は公式ドキュメントにあります
Session.flush(), Session.commit()
(ドキュメント読んでも、ちょっと難しかったです;)

公式ドキュメントを読んでわかった範囲で、commit()の他の特徴
・デフォルトモードのautocommit = Falseでセッションを使用すると、コミットの直後に新しいトランザクションが開始されます。

この機能があるから、session.close()しても その後でもセッションを生成せずにflush()とかcommit()ができちゃうんでしょうかね?
もしわかる方いたら教えてもらえると嬉しいです。

25
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?