Come disabilitare temporaneamente le chiavi esterne in Amazon RDS PostgreSQL?


10

Sto migrando l'ambiente di test esistente su Amazon RDS PostgreSQL. Il framework di test ha una funzione di ricaricare i dati in alcune tabelle in uno stato precedente. Per questo disabilita le chiavi esterne, elimina i dati esistenti, carica lo stato di salvataggio e abilita nuovamente le chiavi esterne.

Attualmente, il framework di test disabilita le chiavi esterne disabilitando tutti i trigger (ovviamente, questo richiede un superutente):

alter table tablename disable trigger all;

Su RDS, questo non riesce con:

ERRORE: autorizzazione negata: "RI_ConstraintTrigger_a_20164" è un trigger di sistema

Come posso disabilitare temporaneamente le chiavi esterne in Amazon RDS PostgreSQL?

Nota: una domanda simile è già stata posta ( PostgreSQL su RDS: come importare in blocco i dati con vincoli FK? ) Ma riguardava specificamente l'importazione offline e la soluzione è specifica anche per l'importazione offline.


Forse questa dovrebbe essere una domanda stackoverflow?
Piotr Findeisen,

Non sono d'accordo: è chiaramente correlato all'amministrazione del database.
Vérace,

Come si disabilitano gli FK ora? Perché ti aspetti che sia diverso su RDS? Inoltre, perché non provarti?
dezso

@dezso, grazie per il commento. Certo, ho aggiunto il codice utilizzato su PostgreSQL non RDS.
Piotr Findeisen,

Oh sì, in questo modo non funzionerà. Ma che ne dici di abbandonare e ricreare i vincoli dell'FK?
dezso

Risposte:


11

session_replication_role

Ho trovato un modo alternativo di disabilitare le chiavi esterne: https://stackoverflow.com/a/18709987

set session_replication_role = replica;

E riattivarli con

set session_replication_role = default;

Funziona su RDS ma richiede ancora privilegi insoliti (cioè non concessi di default).

far cadere e ricreare FK

Una soluzione alternativa è, come suggerito nei commenti, eliminare temporaneamente gli FK. Ciò porta un ulteriore vantaggio nel fatto che i dati vengono verificati quando gli FK vengono riabilitati.

lancio

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

ricreare

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 $$;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.