Amazon RDS PostgreSQL'de yabancı anahtarları geçici olarak nasıl devre dışı bırakabilirim?


10

Mevcut test ortamını Amazon RDS PostgreSQL'e geçiriyorum. Test çerçevesi, belirli tablolardaki verileri daha önceki bir duruma yeniden yükleme özelliğine sahiptir. Bunun için yabancı anahtarları devre dışı bırakır, mevcut verileri siler, yük kaydetme durumunu yükler ve yabancı anahtarları yeniden etkinleştirir.

Şu anda, test çerçevesi tüm tetikleyicileri devre dışı bırakarak yabancı anahtarları devre dışı bırakır (elbette bu süper kullanıcı gerektirir):

alter table tablename disable trigger all;

RDS'de bu başarısız olur:

HATA: izin reddedildi: "RI_ConstraintTrigger_a_20164" bir sistem tetikleyicisidir

Amazon RDS PostgreSQL'de yabancı anahtarları geçici olarak nasıl devre dışı bırakabilirim?

Not: benzer bir soru zaten sorulmuştur ( RDS'de PostgreSQL: FK kısıtlamaları ile veri toplu olarak nasıl alınır? ) Ancak bu özellikle çevrimdışı içe aktarmayla ilgilidir ve çözüm de çevrimdışı içe aktarmaya özgüdür.


Belki de bu bir yığın akışı sorusu olmalı?
Piotr Findeisen

Katılmıyorum - çok açık bir şekilde veritabanı yönetimi ile ilgilidir.
Vérace

FK'ları şimdi nasıl devre dışı bırakıyorsunuz? Neden RDS'de farklı olmasını bekliyorsunuz? Ayrıca, neden kendini denemiyorsun?
dezso

@dezso, yorum için teşekkürler. Tabii ki, RDS olmayan PostgreSQL üzerinde kullanılan kodu ekledim.
Piotr Findeisen

Ah evet, bu şekilde çalışmaz. Peki FK kısıtlamalarını bırakıp yeniden oluşturmaya ne dersiniz?
dezso

Yanıtlar:


11

session_replication_role

Yabancı anahtarları devre dışı bırakmanın alternatif bir yolunu buldum - https://stackoverflow.com/a/18709987

set session_replication_role = replica;

Ve onları yeniden etkinleştirmek

set session_replication_role = default;

Bu, RDS üzerinde çalışır, ancak yine de olağandışı ayrıcalıklar gerektirir (yani varsayılan olarak verilmez).

FK'ları bırakmak ve yeniden yaratmak

Yorumlarda önerildiği gibi, alternatif çözüm FK'leri geçici olarak bırakmaktır. Bu, FK'ler yeniden etkinleştirildiğinde verilerin doğrulanması için ek avantaj sağlar .

damlatma

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 $$;

Canlandırmak

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 $$;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.