LoginSignup
12
10

More than 5 years have passed since last update.

PostgreSQLでトランザクション中の外部キーチェックを外す

Last updated at Posted at 2016-09-23

MySQLばかり触っていたけど、PostgreSQLを使うことになったのでメモ。

いわゆる、MySQLの

SET FOREIGN_KEY_CHECKS=0;

みたいなやつ。

-- 外部キーチェックしない
SET CONSTRAINTS ALL DEFERRED;

-- 外部キーチェックする
SET CONSTRAINTS ALL IMMEDIATE;

transaction中のみ有効な模様。

検索して引っかかったのが、「ALTER TABLE ... DISABLE TRIGGER ALL」とかで絶望していたんだけど、あるやん、って感じ。

ちなみに、見つけたきっかけはLaravelのPostgresGrammarの実装から。

    /**
     * Compile the command to enable foreign key constraints.
     *
     * @return string
     */
    public function compileEnableForeignKeyConstraints()
    {
        return 'SET CONSTRAINTS ALL IMMEDIATE;';
    }

    /**
     * Compile the command to disable foreign key constraints.
     *
     * @return string
     */
    public function compileDisableForeignKeyConstraints()
    {
        return 'SET CONSTRAINTS ALL DEFERRED;';
    }

追記

どうやら、SET CONSTRAINTS ALL DEFERREDはテーブル作成時点で、DEFERRABLEにしておかないと有効にならない模様。

制約にはその生成時点で、DEFERRABLE INITIALLY DEFERRED、DEFERRABLE INITIALLY IMMEDIATE、NOT DEFERRABLEの3つのうちのいずれかの性質が与えられます。 3番目のNOT DEFERRABLE制約は、常にIMMEDIATEモードであり、SET CONSTRAINTSコマンドの影響を受けません。

NOT DEFERRABLE
制約を遅延させることが可能かどうかを制御します。 遅延不可の制約は各コマンドの後すぐに検査されます。 遅延可能な制約の検査は、(SET CONSTRAINTSコマンドを使用して)トランザクションの終了時まで遅延させることができます。 NOT DEFERRABLEがデフォルトです。

デフォルトはNOT DEFERRABLEなので、やっぱり一時的に外部キーを外すしか無さそう…。

12
10
4

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
12
10