Як тимчасово відключити сторонні ключі в Amazon RDS PostgreSQL?


10

Я переміщую існуюче тестове середовище до Amazon RDS PostgreSQL. Тестова основа має особливість перезавантаження даних у певних таблицях до попереднього стану. Для цього він вимикає сторонні ключі, видаляє наявні дані, завантажує стан збереження та знову включає зовнішні ключі.

В даний час тестова рамка вимикає сторонні ключі, вимикаючи всі тригери (звичайно, для цього потрібен суперрузер):

alter table tablename disable trigger all;

У системі RDS це не вдається:

ПОМИЛКА: у дозволі відмовлено: "RI_ConstraintTrigger_a_20164" - це системний тригер

Як я можу тимчасово відключити сторонні ключі в Amazon RDS PostgreSQL?

Примітка: подібне питання вже було задано ( PostgreSQL на RDS: Як об'єднати дані про імпорт із обмеженнями FK? ), Але мова йшла саме про імпорт в режимі офлайн, і рішення стосується і імпорту в автономному режимі.


Можливо, це має бути запитанням про поточний процес?
Piotr Findeisen

Не згоден - це дуже чітко пов'язане з адмініструванням баз даних.
Vérace

Як вимкнути FKs зараз? Чому ви очікуєте, що в RDS це буде інакше? Також, чому б не спробувати себе?
dezso

@dezso, дякую за коментар. Звичайно, я додав код, який використовується у не-RDS PostgreSQL.
Piotr Findeisen

О так, так не вийде. Але як щодо скидання та відтворення обмежень ФК?
dezso

Відповіді:


11

session_replication_role

Я знайшов альтернативний спосіб відключення іноземних ключів - https://stackoverflow.com/a/18709987

set session_replication_role = replica;

І повторно включити їх

set session_replication_role = default;

Це працює на RDS, але все ж вимагає незвичних привілеїв (тобто не надається за замовчуванням).

скидання та відтворення ФК

Альтернативним рішенням є, як це пропонується в коментарях, тимчасове скидання ФК. Це приносить додаткову перевагу в тому, що дані перевіряються при повторному включенні 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 $$;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.