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()ができちゃうんでしょうかね?
もしわかる方いたら教えてもらえると嬉しいです。