ดึง PK และ FK ทั้งหมด


18

ฉันมีฐานข้อมูลขนาดใหญ่ที่ฉันต้องการแยกคีย์หลักและคีย์ต่างประเทศทั้งหมดจากแต่ละตาราง

ฉันมี pgAdmin III

มีวิธีการทำเช่นนี้โดยอัตโนมัติและไม่ข้ามแต่ละตารางด้วยตนเอง?

คำตอบ:


29

คุณสามารถใช้ฟังก์ชันpg_get_constraintdef(constraint_oid)ในแบบสอบถามได้ดังนี้:

SELECT conrelid::regclass AS table_from
     , conname
     , pg_get_constraintdef(oid)
FROM   pg_constraint
WHERE  contype IN ('f', 'p ')
AND    connamespace = 'public'::regnamespace  -- your schema here
ORDER  BY conrelid::regclass::text, contype DESC;

ผลลัพธ์:

 table_from | conname    | pg_get_constraintdef
------------+------------+----------------------
 tbl        | tbl_pkey   | PRIMARY KEY (tbl_id)
 tbl        | tbl_col_fk | FOREIGN KEY (col) REFERENCES tbl2(col) ON UPDATE CASCADE
...

ส่งคืนคีย์หลักและต่างประเทศทั้งหมดสำหรับตารางทั้งหมดในสคีมาที่กำหนดเรียงลำดับตาม tablename, PKs ก่อน

pg_constraintคู่มือเกี่ยวกับ

คู่มือเกี่ยวกับประเภทระบุวัตถุ ( regclass, regnamespace, ... )


1
การดัดแปลงนี้โดยที่เงื่อนไขส่งคืนข้อ จำกัด ที่ไม่เหมือนใครเช่นกัน:WHERE contype IN ('f', 'p', 'u')
Daniel Waltrip

8

ตามวิธีการแก้ปัญหาของเออร์วิน:

SELECT conrelid::regclass AS "FK_Table"
      ,CASE WHEN pg_get_constraintdef(c.oid) LIKE 'FOREIGN KEY %' THEN substring(pg_get_constraintdef(c.oid), 14, position(')' in pg_get_constraintdef(c.oid))-14) END AS "FK_Column"
      ,CASE WHEN pg_get_constraintdef(c.oid) LIKE 'FOREIGN KEY %' THEN substring(pg_get_constraintdef(c.oid), position(' REFERENCES ' in pg_get_constraintdef(c.oid))+12, position('(' in substring(pg_get_constraintdef(c.oid), 14))-position(' REFERENCES ' in pg_get_constraintdef(c.oid))+1) END AS "PK_Table"
      ,CASE WHEN pg_get_constraintdef(c.oid) LIKE 'FOREIGN KEY %' THEN substring(pg_get_constraintdef(c.oid), position('(' in substring(pg_get_constraintdef(c.oid), 14))+14, position(')' in substring(pg_get_constraintdef(c.oid), position('(' in substring(pg_get_constraintdef(c.oid), 14))+14))-1) END AS "PK_Column"
FROM   pg_constraint c
JOIN   pg_namespace n ON n.oid = c.connamespace
WHERE  contype IN ('f', 'p ')
AND pg_get_constraintdef(c.oid) LIKE 'FOREIGN KEY %'
ORDER  BY pg_get_constraintdef(c.oid), conrelid::regclass::text, contype DESC;

จะส่งคืนตารางแบบฟอร์ม:

| FK_Table | FK_Column | PK_Table | PK_Column |

4

ไม่จำเป็นต้องแยกวิเคราะห์pg_get_constraintdef()เพียงใช้คอลัมน์ของpg_constraintตารางเพื่อรับรายละเอียดอื่น ๆ ( เอกสาร) )

นี่คือconstraint_type:

  • p - คีย์หลัก ,
  • f - รหัสต่างประเทศ ,
  • คุณ - ไม่เหมือนใคร ,
  • ค - จำกัด การตรวจสอบ ,
  • x - ยกเว้น ,
  • ...

ตามคำตอบของเออร์วิน :

SELECT c.conname                                     AS constraint_name,
       c.contype                                     AS constraint_type,
       sch.nspname                                   AS "schema",
       tbl.relname                                   AS "table",
       ARRAY_AGG(col.attname ORDER BY u.attposition) AS columns,
       pg_get_constraintdef(c.oid)                   AS definition
FROM pg_constraint c
       JOIN LATERAL UNNEST(c.conkey) WITH ORDINALITY AS u(attnum, attposition) ON TRUE
       JOIN pg_class tbl ON tbl.oid = c.conrelid
       JOIN pg_namespace sch ON sch.oid = tbl.relnamespace
       JOIN pg_attribute col ON (col.attrelid = tbl.oid AND col.attnum = u.attnum)
GROUP BY constraint_name, constraint_type, "schema", "table", definition
ORDER BY "schema", "table";

ผลการค้นหาจะได้รับคำสั่งจากและschematable

หมายเหตุทางเทคนิค: ดูคำถามนี้with ordinalityเกี่ยวกับ


1

เมื่อเร็ว ๆ นี้มีการใช้สิ่งนี้สำหรับ Data Access Layer ที่สร้างยูทิลิตี้ CRUD ตามสคีมาข้อมูลและจบลงด้วยสิ่งนี้

SELECT

    current_schema() AS "schema",
    current_catalog AS "database",
    "pg_constraint".conrelid::regclass::text AS "primary_table_name",
    "pg_constraint".confrelid::regclass::text AS "foreign_table_name",

    (
        string_to_array(
            (
                string_to_array(
                    pg_get_constraintdef("pg_constraint".oid),
                    '('
                )
            )[2],
            ')'
        )
    )[1] AS "foreign_column_name",

    "pg_constraint".conindid::regclass::text AS "constraint_name",

    TRIM((
        string_to_array(
            pg_get_constraintdef("pg_constraint".oid),
            '('
        )
    )[1]) AS "constraint_type",

    pg_get_constraintdef("pg_constraint".oid) AS "constraint_definition"

FROM pg_constraint AS "pg_constraint"

JOIN pg_namespace AS "pg_namespace" ON "pg_namespace".oid = "pg_constraint".connamespace

WHERE

    "pg_constraint".contype IN ( 'f', 'p' )
    AND
    "pg_namespace".nspname = current_schema()
    AND
    "pg_constraint".conrelid::regclass::text IN ('whatever_table_name')
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.