Amazon RDS PostgreSQLで外部キーを一時的に無効にする方法は?


10

既存のテスト環境をAmazon RDS PostgreSQLに移行しています。テストフレームワークには、特定のテーブルのデータを以前の状態にリロードする機能があります。このため、外部キーを無効にし、既存のデータを削除し、保存状態をロードして、外部キーを再度有効にします。

現在、テストフレームワークはすべてのトリガーを無効にすることで外部キーを無効にします(もちろん、これにはスーパーユーザーが必要です)。

alter table tablename disable trigger all;

RDSでは、これは失敗します。

エラー:拒否された権限:「RI_ConstraintTrigger_a_20164」はシステムトリガーです

Amazon RDS PostgreSQLで外部キーを一時的に無効にするにはどうすればよいですか?

注:同様の質問がすでに尋ねられています(RDS上のPostgreSQL:FK制約を使用してデータを一括インポートする方法は?


おそらくこれはスタックオーバーフローの質問でしょうか?
Piotr Findeisen 2015

そう思わない-それはデータベース管理に非常に明確に関連しています。
Vérace

FKを無効にするにはどうすればよいですか?なぜRDSでは異なるものになると思いますか?また、自分で試してみませんか?
dezso 2015

@dezso、コメントありがとうございます。もちろん、RDS以外のPostgreSQLで使用されるコードを追加しました。
Piotr Findeisen 2015

そうそう、この方法ではうまくいきません。しかし、FK制約を削除して再作成するのはどうですか?
dezso 2015

回答:


11

session_replication_role

外部キーを無効にする別の方法を見つけました-https://stackoverflow.com/a/18709987

set session_replication_role = replica;

そしてそれらを再び有効にする

set session_replication_role = default;

これはRDSで機能しますが、通常とは異なる特権が必要です(つまり、デフォルトでは付与されていません)。

FKの削除と再作成

コメントで提案されているように、代替ソリューションは一時的にFKを削除することです。これにより、FKが再度有効になったときにデータが検証されるという利点があります。

落とす

create table if not exists dropped_foreign_keys (
        seq bigserial primary key,
        sql text
);

do $$ declare t record;
begin
    for t in select conrelid::regclass::varchar table_name, conname constraint_name,
            pg_catalog.pg_get_constraintdef(r.oid, true) constraint_definition
            from pg_catalog.pg_constraint r
            where r.contype = 'f'
            -- current schema only:
            and r.connamespace = (select n.oid from pg_namespace n where n.nspname = current_schema())
        loop

        insert into dropped_foreign_keys (sql) values (
            format('alter table %s add constraint %s %s',
                quote_ident(t.table_name), quote_ident(t.constraint_name), t.constraint_definition));

        execute format('alter table %s drop constraint %s', quote_ident(t.table_name), quote_ident(t.constraint_name));

    end loop;
end $$;

再作成

do $$ declare t record;
begin
    -- order by seq for easier troubleshooting when data does not satisfy FKs
    for t in select * from dropped_foreign_keys order by seq loop
        execute t.sql;
        delete from dropped_foreign_keys where seq = t.seq;
    end loop;
end $$;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.