Mengambil semua PK dan FK

18

Saya memiliki database besar yang perlu saya ekstrak semua kunci utama dan kunci asing dari setiap tabel.

Saya punya pgAdmin III.

Apakah ada cara untuk melakukan ini secara otomatis dan tidak membahas setiap tabel secara manual?

Nick Ginanto
sumber

Jawaban:

29

Anda dapat menggunakan fungsi pg_get_constraintdef(constraint_oid)dalam kueri seperti berikut:

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;

Hasil:

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

Mengembalikan semua kunci utama dan asing untuk semua tabel dalam skema yang diberikan, diperintahkan oleh tablename, PKs terlebih dahulu.

Manual tentang pg_constraint.

Manual tentang jenis objek identifier ( regclass, regnamespace, ...).

Erwin Brandstetter
sumber
1
Kondisi yang dimodifikasi ini mengembalikan kendala unik juga:WHERE contype IN ('f', 'p', 'u')
Daniel Waltrip
8

Berdasarkan solusi 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;

Akan mengembalikan tabel formulir:

| FK_Table | FK_Column | PK_Table | PK_Column |
profimedica
sumber
4

Tidak perlu menguraikan pg_get_constraintdef(), cukup gunakan kolom pg_constrainttabel untuk mendapatkan detail lainnya ( dokumen ).

Di sini constraint_typebisa:

  • p - kunci utama ,
  • f - kunci asing ,
  • kamu - unik ,
  • c - periksa kendala ,
  • x - pengecualian ,
  • ...

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

Hasil dipesan oleh schemadan table.

Catatan teknis: lihat pertanyaan ini tentang with ordinality.

Evgeny Nozdrev
sumber
0

Baru-baru ini harus mengimplementasikan ini untuk Lapisan Akses Data yang membangun utilitas CRUD berdasarkan skema info, akhirnya dengan ini.

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')
hajikelist
sumber