Lấy tất cả PK và FK


18

Tôi có một cơ sở dữ liệu lớn mà tôi cần trích xuất tất cả các khóa chính và khóa ngoại từ mỗi bảng.

Tôi có pgAdmin III.

Có cách nào để làm điều này tự động và không đi qua từng bảng một cách thủ công không?

Câu trả lời:


29

Bạn có thể sử dụng hàm pg_get_constraintdef(constraint_oid)trong một truy vấn như sau:

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;

Kết quả:

 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
...

Trả về tất cả các khóa chính và khóa ngoài cho tất cả các bảng trong lược đồ đã cho, được sắp xếp theo tablename, PK trước.

Hướng dẫn về pg_constraint.

Tài liệu hướng dẫn về các loại định danh đối tượng ( regclass, regnamespace, ...).


1
Điều này được sửa đổi khi điều kiện cũng trả về bất kỳ ràng buộc duy nhất nào:WHERE contype IN ('f', 'p', 'u')
Daniel Waltrip

8

Dựa trên giải pháp Erwin:

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;

Sẽ trả về một bảng biểu mẫu:

| FK_Table | FK_Column | PK_Table | PK_Column |

4

Không cần phân tích cú pháp pg_get_constraintdef(), chỉ cần sử dụng các cột của pg_constraintbảng để có được các chi tiết khác ( các tài liệu ).

Đây constraint_typecó thể là:

  • p - khóa chính ,
  • f - khóa ngoại ,
  • u - độc đáo ,
  • c - kiểm tra ràng buộc ,
  • x - loại trừ ,
  • ...

Dựa trên câu trả lời của Erwin :

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

Kết quả được sắp xếp theo schematable.

Lưu ý kỹ thuật: xem câu hỏi này về with ordinality.


0

Gần đây đã phải thực hiện điều này cho Lớp truy cập dữ liệu xây dựng các tiện ích CRUD dựa trên lược đồ thông tin, kết thúc với việc này.

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')
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.