Làm cách nào để tạm thời vô hiệu hóa khóa ngoại trong Amazon RDS PostgreSQL?


10

Tôi đang di chuyển môi trường thử nghiệm hiện tại sang Amazon RDS PostgreSQL. Khung kiểm tra có tính năng tải lại dữ liệu trong các bảng nhất định về trạng thái trước đó. Đối với điều này, nó vô hiệu hóa khóa ngoại, xóa dữ liệu hiện có, tải trạng thái lưu và bật lại khóa ngoại.

Hiện tại, khung kiểm tra vô hiệu hóa các khóa ngoại bằng cách vô hiệu hóa tất cả các kích hoạt (tất nhiên, điều này đòi hỏi siêu người dùng):

alter table tablename disable trigger all;

Trên RDS, điều này không thành công với:

LRI: quyền bị từ chối: "RI_ConstraintTrigger_a_20164" là một kích hoạt hệ thống

Làm cách nào tôi có thể tạm thời vô hiệu hóa các khóa ngoại trong Amazon RDS PostgreSQL?

Lưu ý: câu hỏi tương tự đã được đặt ra ( PostgreSQL trên RDS: Cách nhập hàng loạt dữ liệu với các ràng buộc FK? ) Nhưng đó là cụ thể về nhập ngoại tuyến và giải pháp cũng dành riêng cho nhập ngoại tuyến.


Có lẽ đây là một câu hỏi stackoverflow?
Piotr Findeisen

Không đồng ý - nó rất rõ ràng liên quan đến quản trị cơ sở dữ liệu.
Vérace

Làm thế nào để bạn vô hiệu hóa FK bây giờ? Tại sao bạn mong đợi nó khác với RDS? Ngoài ra, tại sao không thử bản thân?
dezso

@dezso, cảm ơn vì nhận xét. Chắc chắn, tôi đã thêm mã được sử dụng trên PostgreSQL không phải RDS.
Piotr Findeisen

Ồ vâng, cách này sẽ không hiệu quả. Nhưng làm thế nào về việc thả và tái tạo các ràng buộc FK?
dezso

Câu trả lời:


11

session_Vplication_role

Tôi đã tìm thấy một cách khác để vô hiệu hóa khóa ngoại - https://stackoverflow.com/a/18709987

set session_replication_role = replica;

Và kích hoạt lại chúng với

set session_replication_role = default;

Điều này hoạt động trên RDS nhưng vẫn yêu cầu các đặc quyền bất thường (nghĩa là không được cấp theo mặc định).

thả và tái tạo FK

Giải pháp thay thế là, như được đề xuất trong các bình luận, tạm thời bỏ FK. Điều này mang lại lợi thế bổ sung rằng dữ liệu được xác minh khi FK được kích hoạt lại.

Rơi

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

Tái tạo

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 $$;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.