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
なので、やっぱり一時的に外部キーを外すしか無さそう…。