Postgres : 테이블 외래 키를 나열하는 SQL


219

SQL을 사용하여 주어진 테이블에 대한 모든 외래 키를 나열하는 방법이 있습니까? 나는 테이블 이름 / 스키마를 알고 그것을 연결할 수 있습니다.


@Magnus 'answer 을 사용하는 것이 좋습니다 . 가장 간단하고 깨끗하며 가장 빠릅니다.
Erwin Brandstetter

답변:


373

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
제약 조건에 여러 열이있을 때 중단됩니다. information_schema BTW를 사용하여 pk 열을 fk 열과 연결하는 적절한 방법이없는 것 같습니다.
fionbio

5
실제로 제약 조건에 둘 이상의 열이 있습니다. Postgres의 경우 pg_catalog 스키마에서이 정보를 얻는 방법이 있습니다. 아래 답변을 참조하십시오.
마틴

9
쿼리가 잘못되었습니다. 제약 조건 이름을 반복 할 수 없다고 가정합니다. 이는 거짓입니다. 이름이 같은 제약 조건은 다른 네임 스페이스에 존재할 수 있습니다. constraint_name을 사용하여 조인합니다. 또한 두 제약 조건이 같은지 확실하지 않으므로 constraint_name 및 스키마 이름 모두에 참여해도 작동하지 않습니다. 유일한 옵션은 pg_constraints, pg_class 등이 oid를 사용하여 조인하는 것입니다. Postgres의 ANSI 카탈로그는 규정 준수를 위해서만 존재하지만 결함이 있습니다. 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는 내가보고있는 테이블의 OID입니다. 테이블 이름을 다음과 같이 regclass로 캐스팅하여 얻을 수 있습니다.

WHERE r.conrelid = 'mytable'::regclass

테이블 이름이 고유하지 않은 경우 (또는 이름이 첫 번째 인 경우) 스키마 한정 search_path:

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

2
이것은 매우 편리합니다! Postgres에는 이와 같이 백만 개의 작은 기능이있어 모든 것을 간단하게 만듭니다. 이제 그들을 기억하는 방법?
epic_fil

5
@ 필 : 일반적인 아이디어 만 있으면됩니다. 매뉴얼이 나머지를 기억하도록하십시오.
Erwin Brandstetter

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?
Poutrathor

49

문제 \d+ tablenamePostgreSQL의 프롬프트에는 테이블 컬럼의 데이터 유형을 보여주는뿐만 아니라 그것은 인덱스와 외부 키를 보여줄 것이다.


죄송합니다. 내 의견이 잘리지 않았습니다. 적어도 한 번 시도하면 외래 키 매핑도 표시됩니다.
Gre Hahn

45

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

8.4 이전에는 unnest 함수를 처음 작성해야합니다. wiki.postgresql.org/wiki/Array_Unnest
maletin

이 쿼리에서 테이블 이름을 어디에 삽입합니까? 위의 그대로 입력하면 PSQL DB에서 수십 개의 외래 키가있는 0 개의 행이 반환됩니다.
Phrogz

4
'child_table'과 'child_schema'를 테이블 이름과 스키마로 바꾸십시오
martin

이것은 fkey의 이름을 알려주지 않습니다.
Evan Carroll

@EvanCarroll 키 이름을 포함하도록 답변을 업데이트했습니다.
martin

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 post를 확인하고 도움이 될 때 이것을 표시하는 것을 잊지 마십시오.

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

PostgreSQL 9.1에서 작동하는 두 개의 SQL을 제공합니다 (잘못된 이스케이프를 수정하면 '표 이름'없이 (스키마 접두어 없음) SQL에 입력).
alfonx 2016 년

2
+1 : 중복을 반환하지 않는 유일한 솔루션입니다.
Olivier MATROT

이 솔루션에 잘 작동하고 중복을 반환하지 않습니다.
Fuhrmann

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에서 여러 필드를 처리합니다.
Igor

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
Jack Kinsella

5

기존 답변 중 어느 것도 실제로 내가 원하는 것을 원하는 형식으로 결과를 얻지 못했습니다. 따라서 외래 키에 대한 정보를 찾는 (gargantuan) 쿼리는 다음과 같습니다.

몇 가지 참고 사항 :

  • Postgres 9.4 이상에서 생성 from_cols하고 사용하는 표현 to_colsWITH ORDINALITY내가 사용하는 창 기능을 사용하는 해커가 아닌 Postgres 9.4 이상에서 크게 단순화 될 수 있습니다 .
  • 동일한 표현식은 쿼리 플래너에 의존하여에서 반환 된 결과의 순서를 변경하지 않습니다. UNNEST . 나는 그렇게 생각하지 않지만 테스트 할 데이터 세트에 여러 열 외래 키가 없습니다. 9.4 Niceness를 추가하면이 가능성을 완전히 제거 할 수 있습니다.
  • 쿼리 자체에는 Postgres 9.0 이상이 필요합니다 (8.x는 ORDER BY집계 함수를 허용하지 않음 )
  • 교체 STRING_AGGARRAY_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

키가 참조하는 기본 키의 이름을 사용하고 information_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 메일 링리스트의 Andreas Joseph Krogh가 작성한 솔루션입니다. 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

Martin의 탁월한 답변을 확장하려면 여기에 부모 테이블을 기준으로 필터링하고 각 부모 테이블을 사용하여 자식 테이블의 이름을 표시하는 쿼리가 있습니다. 부모 테이블.

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
허용 된 답변의 쿼리는 ~ 0.03 쿼리에 1.2 초를 추가하고 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 업데이트 난 당신이 제거한다고 생각합니다 그래서 또한, 외래 키는,뿐만 아니라 UNIQUE 제약 조건에 따라 달라질 수 있습니다 : pks.CONSTRAINT_TYPE조건을 그냥 가입 할 수 있습니다 rckcu_primary직접
easd

나는 비슷한 대답을 여기에 만들었다 : stackoverflow.com/a/62260908/9093051
11

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 로 옮겨졌습니다 . 이것을 지적 해 주셔서 감사합니다.
Reece


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

이것은 내가 현재 사용하고있는 것으로, 테이블을 나열하고 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')

0

답변을 전적으로 기반으로 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"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.