✍🏻

SQLAlchemy flush超入門

2023/12/12に公開

シンプルフォームの中仙道(@hinata17100) です。本記事は SimpleForm Advent Calendar 2023 の12日目の記事となっています。

本記事ではPythonの中でよく利用されているORMの1つであるSQLAlchemyの「flush」についてご紹介します。

flushとは

flushとは、addとcommitの間というイメージをするとわかりやすいです。どういうことかというと、DB上に一時的に保存はされてはいるけどrollbackが可能な状態です。

動作の例

文章ではわかりにくいと思うので実際に動作を見てみましょう。

game.nameがvalorantのとき
(autocommit=Falseの場合が前提)

# 初期状態ではgame.nameに"valorant"が登録されている
game.name = "fortnite"
db.session.flush()
# flushしたのでgame.nameが"fortnite"に変更されている
db.session.rollack()
# rollbackしたのでgame.nameが"valorant"に戻っている

このように一時的にDBに保存されるがrollbackが可能な状態を作り出すことができます。

どんな時に使えるのか

例えば、上記のようなDB構造でplayersテーブルのidカラムにauto_incrementを導入している場合には、playersのレコードを登録するときに同時に生成されたidをそのまま参照してranksテーブルのレコードを生成したいですよね。
そういった場合には下記のような処理を行うことで実現することができます。

try:
    player = Player(
        name="martian",
    )
    db.session.add(player)
    db.session.flush() #ここで一時的に保存される
    rank = Rank(
        player_id=player.id,
        rank=1,
    )
    db.session.commit() #ここで完全に保存される
except Exception:
    db.session.rollback() #処理に失敗した場合はここで一時的に保存されたものが削除される
finally:
    db.session.close()

このような処理順序で行うことで、playersテーブルに一時保存された際に生成されたidを参照し、ranksテーブルの外部キーであるplayer_idにレコードの登録が可能となります。
もしranksテーブルへの登録が失敗したとしてもrollbackでplayersテーブルへの登録がなかったことにできます。

さいごに

flushについてご紹介しました。意外と便利なので使ってみてはいかがでしょうか。

Discussion