Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

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

いわゆる、MySQLの

SET FOREIGN_KEY_CHECKS=0;

みたいなやつ。

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

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

transaction中のみ有効な模様。

https://www.postgresql.jp/document/9.5/html/sql-set-constraints.html

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

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

https://github.com/laravel/framework/blob/master/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php

    /**
     * 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にしておかないと有効にならない模様。

https://www.postgresql.jp/document/9.5/html/sql-set-constraints.html

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

https://www.postgresql.jp/document/9.5/html/sql-createtable.html

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

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away