Постгреси: SQL для переліку зовнішніх ключів таблиці


220

Чи існує спосіб використання SQL для списку всіх зовнішніх ключів для даної таблиці? Я знаю ім'я таблиці / схему, і я можу це підключити.


Я пропоную скористатися відповіддю @Magnus . Найпростіший, найчистіший, найшвидший.
Erwin Brandstetter

Відповіді:


374

Це можна зробити за допомогою таблиць 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';

8
table_name = 'mytable' має бути tc.table_name = 'mytable', інакше він видає неоднозначну помилку
intrepion

15
+1, дуже корисно. Щоб зробити запит більш надійним, він, ймовірно, повинен також приєднатися до constraint_schema, оскільки для двох схем можливі обмеження з тим самим іменем. Щось на кшталт: 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)
EMP

8
Це перерви, коли в обмеженні є кілька стовпців, чи не так? Здається, немає правильного способу пов’язувати стовпці pk з стовпцями fk, використовуючи BTW information_schema.
fionbio

5
Він дійсно розбивається з більш ніж одним стовпцем у обмеженні. Для Postgres існує спосіб отримання цієї інформації зі схеми pg_catalog. Дивіться мою відповідь нижче.
Мартін

9
Запит неправильний. Він передбачає, що імена обмежень не можуть повторюватися, що є помилковим. Обмеження з одним іменем можуть існувати в різних просторах імен. Ви використовуєте constraint_name для приєднання. Також приєднання до імені constraint_name та до схеми не працюватиме, оскільки ви не впевнені, що два обмеження однакові. Єдиний варіант - це для pg_constraints, pg_class тощо, використовуючи oids для приєднання. Каталог ANSI Postgres існує лише на відповідність, але він недосконалий. pg_catalog - це шлях. Правильна відповідь - тут dba.stackexchange.com/questions/36979/retrieving-all-pk-and-fk
Tulains Córdova

69

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 є таблицею таблиці, яку я переглядаю - ви можете її отримати, просто ввівши своє ім'я таблиці в реклам, як:

WHERE r.conrelid = 'mytable'::regclass

Схематично визначте схему назви таблиці, якщо вона не є унікальною (або першою у вашій search_path):

WHERE r.conrelid = 'myschema.mytable'::regclass

2
Це дуже зручно! Здається, у Postgres мільйон маленьких функцій, які роблять все простішим. Тепер як їх запам'ятати?
epic_fil

5
@Phil: Вам потрібна лише загальна ідея. Нехай керівництво запам'ятає решту.
Ервін Брандстеттер

3
перерахувати всі зовнішні ключі, орієнтовані на таблицю:SELECT conname, pg_catalog.pg_get_constraintdef(r.oid, true) as condef FROM pg_catalog.pg_constraint r WHERE r.confrelid = 'myschema.mytable'::regclass;
regilero

1
@ErwinBrandstetter Як мені це зробити, щоб отримати ім'я іноземної таблиці?
Веллінгтон Сільва Рібейро

2
Я не розумію, яку команду слід використовувати? psql -E -U username -d database ThenWHAT?
Путратор

49

Випуск \d+ tablenameу запиті PostgreSQL, крім показу типів даних стовпців таблиці, він відображатиме індекси та зовнішні ключі.


Вибачте, не помітили, що мій коментар був обрізаний. Якби ви могли хоч раз спробувати його, ви побачили б і відображення зовнішніх ключових відображень.
Гре Хан

45

Відповідь Олліка хороша, оскільки не є специфічною для 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

перед 8.4 спочатку слід створити функцію unnest. wiki.postgresql.org/wiki/Array_Unnest
maletin

Де в цей запит вставити назву таблиці? Введене дослівно введене вище, повертає 0 рядків у моєму DB-БД, що містить десятки іноземних ключів.
Фрогз

4
Ви замінюєте 'child_table' та 'child_schema' назви таблиці та її схеми
martin

це не вказує вам ім'я фкі.
Еван Керролл

@EvanCarroll Я оновив свою відповідь, щоб включити ім'я ключа.
Мартін

31

Розширення до рецепта 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';


Дякую, ідеально підходить для повторного використання.
schellingerht

16

перевірте посаду 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');

Пропонує два SQL, які працюють на PostgreSQL 9.1 (як тільки ви виправите неправильний вхід, введіть своє "ім'я таблиці" (без схеми-префікса) у SQL).
alfonx

2
+1: це єдине рішення, яке не повертає дублікатів.
Олів'є МАТРОТ

до цього рішення працює нормально і не повертає дублікатів.
Фурман

1
Це рішення покаже лише перший стовпчик будь-якого стовпчика із стовпцями, але він виглядає набагато простішим, ніж той, який я щойно опублікував, що зробить кратні.
dewin

12

Цей запит працює правильно і зі складеними ключами:

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

2
Ви приєднуєтесь до стовпців на "constraint_name", тому це працюватиме лише у тому випадку, якщо всі ваші імена обмежень унікальні (для всіх таблиць у всіх схемах). Зазвичай це не є вимогою, і, таким чином, не застосовується до бази даних.
Zilk

3
Дякую. Це єдина відповідь, яка показує, як використовувати information_schema для правильної обробки кількох стовпців.
Самуель Даніельсон

Це рішення працює. Він не видає дублікатів і обробляє декілька полів у FK.
Ігор

9

Я думаю, що ви шукали і дуже близькі до того, що написав @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';

Тут буде перераховано всі таблиці, які використовують вказану таблицю як зовнішній ключ


9

коротке, але миле оновлення, якщо воно працює для вас.

select  * from information_schema.key_column_usage where constraint_catalog=current_catalog and table_name='your_table_name' and position_in_unique_constraint notnull;

Я працював на чарі, як я пишу з PG 12.2
Джек Кінселла,

5

Жодна з існуючих відповідей не дала мені результатів у тому вигляді, в якому я насправді цього хотів. Отже, ось мій (гаргантуанський) запит на пошук інформації про зовнішні ключі.

Кілька приміток:

  • Вирази, які використовуються для генерування from_colsта to_colsможуть бути значно спрощені на Postgres 9.4 та новіших версіяхWITH ORDINALITY а не хакером, який використовує вікно, який використовую.
  • Ці ж вирази покладаються на планувальник запитів, не змінюючи повернутий порядок результатів UNNEST . Я не думаю, що це буде, але в моєму наборі даних немає жодних стовпчикових клавіш із стовпчиками. Додавання 9,4 приємностей взагалі виключає таку можливість.
  • Сам запит вимагає Postgres 9.0 або новішої версії (8.x не дозволяє 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;

5

Ще один спосіб:

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
;


4

Використовуйте ім'я Первинного ключа, на який Клавіші посилаються, і запитуйте інформацію_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" - назва первинного ключа, на який посилаються іноземні ключі.


4

Ось рішення Андреаса Джозефа Крога зі списку розсилки 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;

4

Щоб розширити чудову відповідь Мартіна, тут є запит, який дозволяє фільтрувати на основі батьківської таблиці та показує вам ім'я дочірньої таблиці за кожною батьківською таблицею, щоб ви могли бачити всі залежні таблиці / стовпці на основі обмежень іноземних ключів у батьківська таблиця.

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%'       

1
Запит у прийнятій відповіді додає 1,2 секунди до ~ 0,03 запиту, ваш додає лише 0,01, дякую!
AVProgrammer

3

Правильне рішення проблеми, використовуючи 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.


Інформаційна схема здається правильною відповіддю, але дуже потрібні таблиці pg_catalog: pg_constraint і т.д. Нас це сильно покусало. якщо у вашій базі даних є велика кількість обмежень, можуть виникнути проблеми ...
hajikelist

Наведена вище умова ORDINAL_POSITIONможе дати невірний результат, коли порядок стовпців у зовнішньому ключі відрізняється від порядку стовпців в унікальному обмеженні. Я вважаю, що вам слід було б приєднатись до kcu_foreign.POSITION_IN_UNIQUE_CONSTRAINT = kcu_primary.ORDINAL_POSITION оновлення . Також зовнішній ключ може залежати і від УНІКАЛЬНОГО обмеження, тому я думаю, ви повинні видалити pks.CONSTRAINT_TYPEумову і можете просто приєднатись безпосередньо rcдоkcu_primary
easd

Я зробив подібну відповідь тут: stackoverflow.com/a/62260908/9093051
EASD

2
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

2

Я написав рішення, яке подобається та використовую часто. Код знаходиться за адресою 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. Я очікую оновлення, якщо потрібно, протягом наступних кількох місяців.

-Рессі


1
Посилання на проект тепер мертве.
pimlottc

@pimlottc: Переведено на bitbucket.org/reece/pgutils . Дякуємо, що вказали на це.
Різ


0

Примітка. Не забувайте замовлення стовпця під час читання стовпців обмежень!

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)

0

Це те, що я зараз використовую, він відображатиме таблицю та обмежує обмеження [видалити табличний пункт, і він перелічить усі таблиці в поточному каталозі]:

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

0

найшвидший для перевірки прямо в баш-відповіді, грунтуючись повністю на цій відповіді

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"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.