จะปิดการใช้งานคีย์ต่างประเทศชั่วคราวใน Amazon RDS PostgreSQL ได้อย่างไร


10

ฉันกำลังย้ายสภาพแวดล้อมการทดสอบที่มีอยู่ไปที่ Amazon RDS PostgreSQL เฟรมเวิร์กการทดสอบมีคุณลักษณะของการโหลดข้อมูลในบางตารางเป็นสถานะก่อนหน้า สำหรับสิ่งนี้จะปิดใช้งานคีย์ต่างประเทศลบข้อมูลที่มีอยู่โหลดบันทึกสถานะและเปิดใช้งานคีย์ต่างประเทศอีกครั้ง

ปัจจุบันกรอบการทดสอบปิดการใช้งานคีย์ต่างประเทศโดยการปิดการใช้งานทริกเกอร์ทั้งหมด (แน่นอนต้องใช้ superuser):

alter table tablename disable trigger all;

ใน RDS สิ่งนี้ล้มเหลวด้วย:

ข้อผิดพลาด: สิทธิ์ที่ถูกปฏิเสธ: "RI_ConstraintTrigger_a_20164" เป็นตัวกระตุ้นระบบ

ฉันจะปิดใช้งานคีย์ต่างประเทศชั่วคราวใน Amazon RDS PostgreSQL ได้อย่างไร

หมายเหตุ: คำถามที่คล้ายกันได้ถูกถามแล้ว ( PostgreSQL บน RDS: วิธีการนำเข้าข้อมูลจำนวนมากด้วยข้อ จำกัด FK? ) แต่เป็นเฉพาะเกี่ยวกับการนำเข้าแบบออฟไลน์และการแก้ปัญหาเฉพาะสำหรับการนำเข้าแบบออฟไลน์ด้วย


บางทีนี่อาจเป็นคำถามของ stackoverflow
Piotr Findeisen

ไม่เห็นด้วย - มันเกี่ยวข้องอย่างชัดเจนกับการบริหารฐานข้อมูล
Vérace

คุณปิดการใช้งาน FK ตอนนี้ได้อย่างไร? ทำไมคุณถึงคิดว่ามันต่างจาก RDS? นอกจากนี้ทำไมไม่ลองด้วยตัวเอง?
dezso

@dezso ขอบคุณสำหรับความคิดเห็น แน่นอนว่าฉันเพิ่มรหัสที่ใช้กับ PostgreSQL ที่ไม่ใช่ RDS
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 ใหม่

โซลูชันทางเลือกคือตามที่แนะนำในความคิดเห็นเพื่อทิ้ง FKs ชั่วคราว สิ่งนี้นำมาซึ่งประโยชน์เพิ่มเติมที่ข้อมูลจะได้รับการตรวจสอบเมื่อเปิดใช้งาน 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.