Amazon RDS PostgreSQL에서 외래 키를 일시적으로 비활성화하는 방법은 무엇입니까?


10

기존 테스트 환경을 Amazon RDS PostgreSQL로 마이그레이션하고 있습니다. 테스트 프레임 워크에는 특정 테이블의 데이터를 이전 상태로 다시로드하는 기능이 있습니다. 이를 위해 외래 키를 비활성화하고 기존 데이터를 삭제하고 저장 상태를로드하고 외래 키를 다시 활성화합니다.

현재 테스트 프레임 워크는 모든 트리거를 비활성화하여 외래 키를 비활성화합니다 (물론 수퍼 유저 필요).

alter table tablename disable trigger all;

RDS에서는 다음과 같이 실패합니다.

오류 : 권한 거부 : "RI_ConstraintTrigger_a_20164"는 시스템 트리거입니다

Amazon RDS PostgreSQL에서 외래 키를 일시적으로 비활성화하려면 어떻게해야합니까?

참고 : 비슷한 질문이 이미 제기되었지만 ( RDS의 PostgreSQL : FK 제약 조건으로 데이터를 대량으로 가져 오는 방법? ) 특히 오프라인 가져 오기에 대한 것이며 솔루션은 오프라인 가져 오기에만 해당됩니다.


아마도 이것이 stackoverflow 질문이어야합니까?
Piotr Findeisen

동의하지 않음-데이터베이스 관리와 매우 관련이 있습니다.
Vérace

지금 FK를 어떻게 비활성화합니까? RDS와 다른 이유는 무엇입니까? 또한, 스스로 시도해 보지 않겠습니까?
dezso

@dezso, 의견 주셔서 감사합니다. 물론 RDS가 아닌 PostgreSQL에서 사용되는 코드를 추가했습니다.
Piotr Findeisen

예, 이런 식으로 작동하지 않습니다. 그러나 FK 제약 조건을 삭제하고 다시 만드는 것은 어떻습니까?
dezso

답변:


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.