ฉันมีฐานข้อมูลขนาดใหญ่ที่ฉันต้องการแยกคีย์หลักและคีย์ต่างประเทศทั้งหมดจากแต่ละตาราง
ฉันมี pgAdmin III
มีวิธีการทำเช่นนี้โดยอัตโนมัติและไม่ข้ามแต่ละตารางด้วยตนเอง?
ฉันมีฐานข้อมูลขนาดใหญ่ที่ฉันต้องการแยกคีย์หลักและคีย์ต่างประเทศทั้งหมดจากแต่ละตาราง
ฉันมี pgAdmin III
มีวิธีการทำเช่นนี้โดยอัตโนมัติและไม่ข้ามแต่ละตารางด้วยตนเอง?
คำตอบ:
คุณสามารถใช้ฟังก์ชัน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 ก่อน
คู่มือเกี่ยวกับประเภทระบุวัตถุ ( regclass
, regnamespace
, ... )
ตามวิธีการแก้ปัญหาของเออร์วิน:
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 |
ไม่จำเป็นต้องแยกวิเคราะห์pg_get_constraintdef()
เพียงใช้คอลัมน์ของpg_constraint
ตารางเพื่อรับรายละเอียดอื่น ๆ ( เอกสาร) )
นี่คือconstraint_type
:
ตามคำตอบของเออร์วิน :
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";
ผลการค้นหาจะได้รับคำสั่งจากและschema
table
หมายเหตุทางเทคนิค: ดูคำถามนี้with ordinality
เกี่ยวกับ
เมื่อเร็ว ๆ นี้มีการใช้สิ่งนี้สำหรับ 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')
WHERE contype IN ('f', 'p', 'u')