Postgres: SQL для отображения внешних ключей таблицы - PullRequest
174 голосов
/ 20 июля 2009

Есть ли способ использовать SQL для вывода списка всех внешних ключей для данной таблицы? Я знаю имя таблицы / схему, и я могу подключить это.

Ответы [ 21 ]

310 голосов
/ 20 июля 2009

Вы можете сделать это через таблицы 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';
58 голосов
/ 20 июля 2009

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 - это oid таблицы, на которую я смотрю - вы можете получить ее, просто приведя свое имя таблицы к regclass, как:

WHERE r.conrelid = 'mytable'::regclass

Схема - уточните имя таблицы, если оно не уникально (или первое в вашем search_path):

WHERE r.conrelid = 'myschema.mytable'::regclass
39 голосов
/ 08 июня 2012

Ответ Оллика хорош, поскольку он не специфичен для 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
27 голосов
/ 20 ноября 2015

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

25 голосов
/ 29 июля 2011

Дополнение к рецепту оллика:

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

12 голосов
/ 30 марта 2011

проверьте сообщение 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');
10 голосов
/ 18 июня 2013

Этот запрос корректно работает и с составными ключами:

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
9 голосов
/ 11 декабря 2013

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

Будет выведен список всех таблиц, которые используют указанную таблицу в качестве внешнего ключа

5 голосов
/ 20 июля 2009

Вы можете использовать Системные каталоги PostgreSQL . Возможно, вы можете запросить pg_constraint , чтобы запросить внешние ключи. Вы также можете использовать Информационную схему

4 голосов
/ 12 мая 2015

Чтобы раскрыть превосходный ответ Мартина, вот запрос, который позволяет вам фильтровать на основе родительской таблицы и отображать имя дочерней таблицы с каждой родительской таблицей, чтобы вы могли видеть все зависимые таблицы / столбцы на основе внешней Ключевые ограничения в родительской таблице.

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%'       
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...