มีวิธีใช้ SQL เพื่อแสดงรายการคีย์ต่างประเทศทั้งหมดสำหรับตารางที่กำหนดหรือไม่? ฉันรู้ชื่อตาราง / คีมาและฉันสามารถเสียบมันได้
มีวิธีใช้ SQL เพื่อแสดงรายการคีย์ต่างประเทศทั้งหมดสำหรับตารางที่กำหนดหรือไม่? ฉันรู้ชื่อตาราง / คีมาและฉันสามารถเสียบมันได้
คำตอบ:
คุณสามารถทำได้ผ่านตาราง information_schema ตัวอย่างเช่น:
SELECT
tc.table_schema,
tc.constraint_name,
tc.table_name,
kcu.column_name,
ccu.table_schema AS foreign_table_schema,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name
FROM
information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
AND tc.table_schema = kcu.table_schema
JOIN information_schema.constraint_column_usage AS ccu
ON ccu.constraint_name = tc.constraint_name
AND ccu.table_schema = tc.table_schema
WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name='mytable';
FROM information_schema.table_constraints AS tc JOIN information_schema.key_column_usage AS kcu USING (constraint_schema, constraint_name) JOIN information_schema.constraint_column_usage AS ccu USING (constraint_schema, constraint_name)
psql ทำสิ่งนี้และถ้าคุณเริ่ม psql ด้วย:
psql -E
มันจะแสดงให้คุณเห็นอย่างชัดเจนว่าแบบสอบถามใดที่ถูกเรียกใช้งาน ในกรณีของการหากุญแจต่างประเทศมันคือ:
SELECT conname,
pg_catalog.pg_get_constraintdef(r.oid, true) as condef
FROM pg_catalog.pg_constraint r
WHERE r.conrelid = '16485' AND r.contype = 'f' ORDER BY 1
ในกรณีนี้ 16485 เป็นหมายเลขของตารางที่ฉันกำลังดู - คุณสามารถรับอันนั้นได้โดยเพียงแค่หล่อ tablename เพื่อ regclass เช่น:
WHERE r.conrelid = 'mytable'::regclass
สคีมามีคุณสมบัติชื่อตารางหากไม่ใช่ชื่อเฉพาะ (หรือชื่อแรกของคุณsearch_path
):
WHERE r.conrelid = 'myschema.mytable'::regclass
SELECT conname, pg_catalog.pg_get_constraintdef(r.oid, true) as condef FROM pg_catalog.pg_constraint r WHERE r.confrelid = 'myschema.mytable'::regclass;
psql -E -U username -d database ThenWHAT
?
ปัญหา\d+ tablename
เกี่ยวกับพรอมต์ PostgreSQL นอกเหนือจากการแสดงประเภทข้อมูลของคอลัมน์ตารางมันจะแสดงดัชนีและคีย์ต่างประเทศ
คำตอบของ Ollyc นั้นดีเพราะมันไม่เฉพาะ Postgres แต่มันจะหยุดลงเมื่อคีย์ต่างประเทศอ้างอิงมากกว่าหนึ่งคอลัมน์ แบบสอบถามต่อไปนี้ใช้ได้กับจำนวนคอลัมน์โดยพลการ แต่ต้องอาศัยส่วนขยาย Postgres เป็นอย่างมาก:
select
att2.attname as "child_column",
cl.relname as "parent_table",
att.attname as "parent_column",
conname
from
(select
unnest(con1.conkey) as "parent",
unnest(con1.confkey) as "child",
con1.confrelid,
con1.conrelid,
con1.conname
from
pg_class cl
join pg_namespace ns on cl.relnamespace = ns.oid
join pg_constraint con1 on con1.conrelid = cl.oid
where
cl.relname = 'child_table'
and ns.nspname = 'child_schema'
and con1.contype = 'f'
) con
join pg_attribute att on
att.attrelid = con.confrelid and att.attnum = con.child
join pg_class cl on
cl.oid = con.confrelid
join pg_attribute att2 on
att2.attrelid = con.conrelid and att2.attnum = con.parent
ส่วนต่อขยายไปยังสูตร ollyc:
CREATE VIEW foreign_keys_view AS
SELECT
tc.table_name, kcu.column_name,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name
FROM
information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage
AS kcu ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage
AS ccu ON ccu.constraint_name = tc.constraint_name
WHERE constraint_type = 'FOREIGN KEY';
แล้ว:
SELECT * FROM foreign_keys_view WHERE table_name='YourTableNameHere'
;
ตรวจสอบการโพสต์ ff สำหรับการแก้ปัญหาของคุณและอย่าลืมทำเครื่องหมายนี้เมื่อคุณได้รับประโยชน์นี้
http://errorbank.blogspot.com/2011/03/list-all-foreign-keys-references-for.html
SELECT
o.conname AS constraint_name,
(SELECT nspname FROM pg_namespace WHERE oid=m.relnamespace) AS source_schema,
m.relname AS source_table,
(SELECT a.attname FROM pg_attribute a WHERE a.attrelid = m.oid AND a.attnum = o.conkey[1] AND a.attisdropped = false) AS source_column,
(SELECT nspname FROM pg_namespace WHERE oid=f.relnamespace) AS target_schema,
f.relname AS target_table,
(SELECT a.attname FROM pg_attribute a WHERE a.attrelid = f.oid AND a.attnum = o.confkey[1] AND a.attisdropped = false) AS target_column
FROM
pg_constraint o LEFT JOIN pg_class f ON f.oid = o.confrelid LEFT JOIN pg_class m ON m.oid = o.conrelid
WHERE
o.contype = 'f' AND o.conrelid IN (SELECT oid FROM pg_class c WHERE c.relkind = 'r');
แบบสอบถามนี้ทำงานได้ถูกต้องกับคีย์ผสมเช่นกัน:
select c.constraint_name
, x.table_schema as schema_name
, x.table_name
, x.column_name
, y.table_schema as foreign_schema_name
, y.table_name as foreign_table_name
, y.column_name as foreign_column_name
from information_schema.referential_constraints c
join information_schema.key_column_usage x
on x.constraint_name = c.constraint_name
join information_schema.key_column_usage y
on y.ordinal_position = x.position_in_unique_constraint
and y.constraint_name = c.unique_constraint_name
order by c.constraint_name, x.ordinal_position
ฉันคิดว่าสิ่งที่คุณกำลังมองหาและใกล้เคียงกับสิ่งที่ @ollyc เขียนคือ:
SELECT
tc.constraint_name, tc.table_name, kcu.column_name,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name
FROM
information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage AS ccu
ON ccu.constraint_name = tc.constraint_name
WHERE constraint_type = 'FOREIGN KEY' AND ccu.table_name='YourTableNameHere';
นี่จะแสดงรายการตารางทั้งหมดที่ใช้ตารางที่คุณระบุเป็นรหัสต่างประเทศ
โหวตสั้น ๆ แต่หวานถ้ามันเหมาะกับคุณ
select * from information_schema.key_column_usage where constraint_catalog=current_catalog and table_name='your_table_name' and position_in_unique_constraint notnull;
ไม่มีคำตอบที่มีอยู่ให้ฉันผลลัพธ์ในรูปแบบที่ฉันต้องการพวกเขาจริง ๆ ดังนั้นนี่คือแบบสอบถาม (gargantuan) ของฉันสำหรับการค้นหาข้อมูลเกี่ยวกับกุญแจต่างประเทศ
หมายเหตุเล็กน้อย:
from_cols
และto_cols
สามารถทำให้ง่ายขึ้นอย่างมากใน Postgres 9.4 และใช้ในภายหลังWITH ORDINALITY
มากกว่าการแฮกเกอร์ใช้ฟังก์ชั่นหน้าต่างที่ฉันใช้UNNEST
ผู้ที่แสดงออกเดียวกันจะอาศัยการวางแผนแบบสอบถามไม่เปลี่ยนแปลงคำสั่งซื้อกลับของผลที่ได้จากฉันไม่คิดว่าจะทำได้ แต่ฉันไม่มีคีย์ต่างประเทศหลายคอลัมน์ในชุดข้อมูลของฉันเพื่อทดสอบ การเพิ่มนิโคติน 9.4 จะกำจัดความเป็นไปได้นี้โดยสิ้นเชิงORDER BY
ในฟังก์ชั่นรวม)STRING_AGG
ด้วยARRAY_AGG
หากคุณต้องการอาร์เรย์ของคอลัมน์แทนที่จะเป็นสตริงที่คั่นด้วยเครื่องหมายจุลภาค-
SELECT
c.conname AS constraint_name,
(SELECT n.nspname FROM pg_namespace AS n WHERE n.oid=c.connamespace) AS constraint_schema,
tf.name AS from_table,
(
SELECT STRING_AGG(QUOTE_IDENT(a.attname), ', ' ORDER BY t.seq)
FROM
(
SELECT
ROW_NUMBER() OVER (ROWS UNBOUNDED PRECEDING) AS seq,
attnum
FROM
UNNEST(c.conkey) AS t(attnum)
) AS t
INNER JOIN pg_attribute AS a ON a.attrelid=c.conrelid AND a.attnum=t.attnum
) AS from_cols,
tt.name AS to_table,
(
SELECT STRING_AGG(QUOTE_IDENT(a.attname), ', ' ORDER BY t.seq)
FROM
(
SELECT
ROW_NUMBER() OVER (ROWS UNBOUNDED PRECEDING) AS seq,
attnum
FROM
UNNEST(c.confkey) AS t(attnum)
) AS t
INNER JOIN pg_attribute AS a ON a.attrelid=c.confrelid AND a.attnum=t.attnum
) AS to_cols,
CASE confupdtype WHEN 'r' THEN 'restrict' WHEN 'c' THEN 'cascade' WHEN 'n' THEN 'set null' WHEN 'd' THEN 'set default' WHEN 'a' THEN 'no action' ELSE NULL END AS on_update,
CASE confdeltype WHEN 'r' THEN 'restrict' WHEN 'c' THEN 'cascade' WHEN 'n' THEN 'set null' WHEN 'd' THEN 'set default' WHEN 'a' THEN 'no action' ELSE NULL END AS on_delete,
CASE confmatchtype::text WHEN 'f' THEN 'full' WHEN 'p' THEN 'partial' WHEN 'u' THEN 'simple' WHEN 's' THEN 'simple' ELSE NULL END AS match_type, -- In earlier postgres docs, simple was 'u'nspecified, but current versions use 's'imple. text cast is required.
pg_catalog.pg_get_constraintdef(c.oid, true) as condef
FROM
pg_catalog.pg_constraint AS c
INNER JOIN (
SELECT pg_class.oid, QUOTE_IDENT(pg_namespace.nspname) || '.' || QUOTE_IDENT(pg_class.relname) AS name
FROM pg_class INNER JOIN pg_namespace ON pg_class.relnamespace=pg_namespace.oid
) AS tf ON tf.oid=c.conrelid
INNER JOIN (
SELECT pg_class.oid, QUOTE_IDENT(pg_namespace.nspname) || '.' || QUOTE_IDENT(pg_class.relname) AS name
FROM pg_class INNER JOIN pg_namespace ON pg_class.relnamespace=pg_namespace.oid
) AS tt ON tt.oid=c.confrelid
WHERE c.contype = 'f' ORDER BY 1;
อีกวิธีหนึ่ง:
WITH foreign_keys AS (
SELECT
conname,
conrelid,
confrelid,
unnest(conkey) AS conkey,
unnest(confkey) AS confkey
FROM pg_constraint
WHERE contype = 'f' -- AND confrelid::regclass = 'your_table'::regclass
)
-- if confrelid, conname pair shows up more than once then it is multicolumn foreign key
SELECT fk.conname as constraint_name,
fk.confrelid::regclass as referenced_table, af.attname as pkcol,
fk.conrelid::regclass as referencing_table, a.attname as fkcol
FROM foreign_keys fk
JOIN pg_attribute af ON af.attnum = fk.confkey AND af.attrelid = fk.confrelid
JOIN pg_attribute a ON a.attnum = conkey AND a.attrelid = fk.conrelid
ORDER BY fk.confrelid, fk.conname
;
คุณสามารถใช้แคตตาล็อกระบบ PostgreSQL บางทีคุณสามารถสืบค้นpg_constraintเพื่อขอกุญแจต่างประเทศ คุณยังสามารถใช้โครงสร้างข้อมูล
ใช้ชื่อของคีย์หลักที่คีย์อ้างอิงและสอบถาม data_schema:
select table_name, column_name
from information_schema.key_column_usage
where constraint_name IN (select constraint_name
from information_schema.referential_constraints
where unique_constraint_name = 'TABLE_NAME_pkey')
นี่คือ 'TABLE_NAME_pkey' ชื่อของคีย์หลักที่อ้างอิงโดยคีย์ต่างประเทศ
นี่คือวิธีแก้ปัญหาโดย Andreas Joseph Krogh จากรายชื่อผู้รับจดหมายของ PostgreSQL: http://www.postgresql.org/message-id/200811072134.44750.andreak@officenet.no
SELECT source_table::regclass, source_attr.attname AS source_column,
target_table::regclass, target_attr.attname AS target_column
FROM pg_attribute target_attr, pg_attribute source_attr,
(SELECT source_table, target_table, source_constraints[i] source_constraints, target_constraints[i] AS target_constraints
FROM
(SELECT conrelid as source_table, confrelid AS target_table, conkey AS source_constraints, confkey AS target_constraints,
generate_series(1, array_upper(conkey, 1)) AS i
FROM pg_constraint
WHERE contype = 'f'
) query1
) query2
WHERE target_attr.attnum = target_constraints AND target_attr.attrelid = target_table AND
source_attr.attnum = source_constraints AND source_attr.attrelid = source_table;
โซลูชันนี้จัดการกับคีย์ต่างประเทศที่อ้างอิงหลายคอลัมน์และหลีกเลี่ยงการซ้ำซ้อน (ซึ่งบางคำตอบอื่น ๆ ไม่สามารถทำได้) สิ่งเดียวที่ฉันเปลี่ยนคือชื่อตัวแปร
นี่คือตัวอย่างที่ส่งกลับemployee
คอลัมน์ทั้งหมดที่อ้างอิงpermission
ตาราง:
SELECT source_column
FROM foreign_keys
WHERE source_table = 'employee'::regclass AND target_table = 'permission'::regclass;
หากต้องการขยายคำตอบที่ยอดเยี่ยมของ Martin ที่นี่คือข้อความค้นหาที่ให้คุณกรองตามตารางหลักและแสดงชื่อของตารางลูกกับตารางหลักแต่ละรายการเพื่อให้คุณสามารถดูตาราง / คอลัมน์ที่ขึ้นอยู่กับทั้งหมดตามข้อ จำกัด ของ foreign key ตารางผู้ปกครอง
select
con.constraint_name,
att2.attname as "child_column",
cl.relname as "parent_table",
att.attname as "parent_column",
con.child_table,
con.child_schema
from
(select
unnest(con1.conkey) as "parent",
unnest(con1.confkey) as "child",
con1.conname as constraint_name,
con1.confrelid,
con1.conrelid,
cl.relname as child_table,
ns.nspname as child_schema
from
pg_class cl
join pg_namespace ns on cl.relnamespace = ns.oid
join pg_constraint con1 on con1.conrelid = cl.oid
where con1.contype = 'f'
) con
join pg_attribute att on
att.attrelid = con.confrelid and att.attnum = con.child
join pg_class cl on
cl.oid = con.confrelid
join pg_attribute att2 on
att2.attrelid = con.conrelid and att2.attnum = con.parent
where cl.relname like '%parent_table%'
วิธีการแก้ไขปัญหาที่เหมาะสมการใช้information_schema
การทำงานกับคีย์หลายคอลัมน์การรวมคอลัมน์ของชื่อต่าง ๆ ในตารางทั้งสองอย่างถูกต้องและเข้ากันได้กับ ms sqlsever:
select fks.TABLE_NAME as foreign_key_table_name
, fks.CONSTRAINT_NAME as foreign_key_constraint_name
, kcu_foreign.COLUMN_NAME as foreign_key_column_name
, rc.UNIQUE_CONSTRAINT_NAME as primary_key_constraint_name
, pks.TABLE_NAME as primary_key_table_name
, kcu_primary.COLUMN_NAME as primary_key_column_name
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS fks -- foreign keys
inner join INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu_foreign -- the columns of the above keys
on fks.TABLE_CATALOG = kcu_foreign.TABLE_CATALOG
and fks.TABLE_SCHEMA = kcu_foreign.TABLE_SCHEMA
and fks.TABLE_NAME = kcu_foreign.TABLE_NAME
and fks.CONSTRAINT_NAME = kcu_foreign.CONSTRAINT_NAME
inner join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc -- referenced constraints
on rc.CONSTRAINT_CATALOG = fks.CONSTRAINT_CATALOG
and rc.CONSTRAINT_SCHEMA = fks.CONSTRAINT_SCHEMA
and rc.CONSTRAINT_NAME = fks.CONSTRAINT_NAME
inner join INFORMATION_SCHEMA.TABLE_CONSTRAINTS pks -- primary keys (referenced by fks)
on rc.UNIQUE_CONSTRAINT_CATALOG = pks.CONSTRAINT_CATALOG
and rc.UNIQUE_CONSTRAINT_SCHEMA = pks.CONSTRAINT_SCHEMA
and rc.UNIQUE_CONSTRAINT_NAME = pks.CONSTRAINT_NAME
inner join INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu_primary
on pks.TABLE_CATALOG = kcu_primary.TABLE_CATALOG
and pks.TABLE_SCHEMA = kcu_primary.TABLE_SCHEMA
and pks.TABLE_NAME = kcu_primary.TABLE_NAME
and pks.CONSTRAINT_NAME = kcu_primary.CONSTRAINT_NAME
and kcu_foreign.ORDINAL_POSITION = kcu_primary.ORDINAL_POSITION -- this joins the columns
where fks.TABLE_SCHEMA = 'dbo' -- replace with schema name
and fks.TABLE_NAME = 'your_table_name' -- replace with table name
and fks.CONSTRAINT_TYPE = 'FOREIGN KEY'
and pks.CONSTRAINT_TYPE = 'PRIMARY KEY'
order by fks.constraint_name, kcu_foreign.ORDINAL_POSITION
หมายเหตุ: มีความแตกต่างบางประการระหว่างการประยุกต์ใช้ potgresql และ sqlserver information_schema
ซึ่งทำให้คำตอบสูงสุดให้ผลลัพธ์ที่แตกต่างกันในทั้งสองระบบ - หนึ่งแสดงชื่อคอลัมน์สำหรับตารางคีย์ต่างประเทศอื่น ๆ สำหรับตารางคีย์หลัก ด้วยเหตุนี้ฉันจึงตัดสินใจใช้มุมมอง KEY_COLUMN_USAGE แทน
ORDINAL_POSITION
สามารถให้ผลลัพธ์ที่ไม่ถูกต้องเมื่อลำดับของคอลัมน์ใน foreign key แตกต่างจากลำดับของคอลัมน์ในข้อ จำกัด ที่ไม่ซ้ำกัน ผมเชื่อว่าคุณควรจะได้เข้าร่วมในkcu_foreign.POSITION_IN_UNIQUE_CONSTRAINT = kcu_primary.ORDINAL_POSITION
การปรับปรุง : นอกจากนี้ที่สำคัญต่างประเทศอาจขึ้นอยู่กับข้อ จำกัด ที่ไม่ซ้ำกันเช่นกันดังนั้นฉันคิดว่าคุณควรเอาpks.CONSTRAINT_TYPE
สภาพและก็สามารถเข้าร่วมrc
การkcu_primary
โดยตรง
SELECT r.conname
,ct.table_name
,pg_catalog.pg_get_constraintdef(r.oid, true) as condef
FROM pg_catalog.pg_constraint r, information_schema.constraint_table_usage ct
WHERE r.contype = 'f'
AND r.conname = ct.constraint_name
ORDER BY 1
ฉันเขียนวิธีแก้ปัญหาที่ชอบและใช้บ่อย รหัสอยู่ที่http://code.google.com/p/pgutils/ http://code.google.com/p/pgutils/ดูมุมมอง pgutils.foreign_keys
น่าเสียดายที่ผลลัพธ์มีคำเกินไปที่จะรวมไว้ที่นี่ อย่างไรก็ตามคุณสามารถลองใช้งานฐานข้อมูลสาธารณะได้ที่นี่เช่นนี้:
$ psql -h unison-db.org -U PUBLIC -d unison -c 'select * from pgutils.foreign_keys;
ใช้งานได้กับ 8.3 อย่างน้อย ฉันคาดว่าจะอัปเดตหากจำเป็นในอีกไม่กี่เดือนข้างหน้า
-Reece
ฉันสร้างเครื่องมือเล็ก ๆ น้อย ๆ เพื่อสอบถามแล้วเปรียบเทียบสกีมาฐานข้อมูล: ดัมพ์ PostgreSQL db schema กับข้อความ
มีข้อมูลเกี่ยวกับ FK แต่การตอบกลับ ollyc ให้รายละเอียดเพิ่มเติม
หมายเหตุ: อย่าลืมลำดับคอลัมน์ในขณะที่อ่านคอลัมน์ข้อ จำกัด !
SELECT conname, attname
FROM pg_catalog.pg_constraint c
JOIN pg_catalog.pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = ANY (c.conkey)
WHERE attrelid = 'schema.table_name'::regclass
ORDER BY conname, array_position(c.conkey, a.attnum)
นี่คือสิ่งที่ฉันกำลังใช้อยู่มันจะแสดงรายการตารางและเป็นข้อ จำกัด fkey [ลบส่วนคำสั่งตารางและจะแสดงรายการตารางทั้งหมดในแค็ตตาล็อกปัจจุบัน]:
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
--fkey and pkey constraints
"pg_constraint".contype IN ( 'f', 'p' )
AND
"pg_namespace".nspname = current_schema()
AND
"pg_constraint".conrelid::regclass::text IN ('whatever_table_name')
วิธีที่เร็วที่สุดในการตรวจสอบความถูกต้องของคำตอบแบบ bash โดยอิงจากคำตอบนี้ทั้งหมด
IFS='' read -r -d '' sql_code << EOF_SQL_CODE
SELECT
o.oid
, o.conname AS constraint_name
, (SELECT nspname FROM pg_namespace WHERE oid=m.relnamespace) AS source_schema
, m.relname AS source_table
, (SELECT a.attname FROM pg_attribute a
WHERE a.attrelid = m.oid AND a.attnum = o.conkey[1] AND a.attisdropped = false) AS source_column
, (SELECT nspname FROM pg_namespace
WHERE oid=f.relnamespace) AS target_schema
, f.relname AS target_table
, (SELECT a.attname FROM pg_attribute a
WHERE a.attrelid = f.oid AND a.attnum = o.confkey[1] AND a.attisdropped = false) AS target_column
, ROW_NUMBER () OVER (ORDER BY o.oid) as rowid
FROM pg_constraint o
LEFT JOIN pg_class f ON f.oid = o.confrelid
LEFT JOIN pg_class m ON m.oid = o.conrelid
WHERE 1=1
AND o.contype = 'f'
AND o.conrelid IN (SELECT oid FROM pg_class c WHERE c.relkind = 'r')
EOF_SQL_CODE
psql -d my_db -c "$sql_code"