Postgres:テーブルの外部キーをリストするSQL


219

SQLを使用して特定のテーブルのすべての外部キーを一覧表示する方法はありますか?テーブル名/スキーマを知っているので、それをプラグインできます。


@Magnusの回答を使用することをお勧めします。最も単純、最もクリーン、最速。
Erwin Brandstetter 2013年

回答:


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'である必要があります。そうでない場合は、あいまいなエラーがスローされます
11:23

15
+1、とても役に立った。2つのスキーマが同じ名前の制約を持つことが可能であるため、クエリをより堅牢にするためには、おそらく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を使用しています。また、2つの制約が同じであることを確認できないため、constraint_nameとスキーマ名の両方での結合は機能しません。唯一のオプションは、結合にOIDを使用するpg_constraints、pg_classなどの場合です。PostgresのANSIカタログは準拠のためだけにありますが、欠陥があります。pg_catalogはその先への道です。正解はこちらdba.stackexchange.com/questions/36979/retrieving-all-pk-and-fk
TulainsCórdova'24

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には、このような100万個の小さな関数があり、すべてを単純化しているようです。今、それらをどのように覚えていますか?
epic_fil 2014

5
@フィル:一般的なアイデアだけが必要です。マニュアルに残りを覚えさせてください。
Erwin Brandstetter、2014

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
マレチン

このクエリにテーブル名をどこに挿入しますか?上記をそのまま入力すると、数十の外部キーを持つPSQL DBで0行が返されます。
Phrogz 2013年

4
「child_table」と「child_schema」をテーブルとそのスキーマの名前に置き換えます
martin

これはfkeyの名前を教えてくれません。
エヴァンキャロル

@EvanCarroll回答を更新してキーの名前を含めました。
マルタン2017年

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


ありがとう、再利用に最適です。
シェリンガート2017

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

PostgreSQL 9.1で動作する2つのSQLを提供します(誤ったエスケープを修正したら、「スキーマ名プレフィックスなしの」テーブル名をSQLに挿入します)。
alfonx

2
+1:これは重複を返さない唯一のソリューションです。
Olivier MATROT、2013年

このソリューションでは、正常に動作し、重複を返しません。
Fuhrmann 2015

1
このソリューションでは、複数列の外部キーの最初の列のみが表示されますが、先ほど投稿した複数の列を実行するキーよりもはるかに単純に見えます。
2016

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、2013

3
ありがとう。これは、information_schemaを使用して複数の列を適切に処理する方法を示す唯一の回答です。
Samuel Danielson 2017年

このソリューションは機能します。重複は発生せず、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 nicetiesを追加すると、この可能性が完全に排除されます。
  • クエリ自体には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;

このソリューションは、複数の列を参照する外部キーを処理し、重複を回避します(他の回答の一部は失敗します)。変更したのは変数名だけです。

以下はemployeepermissionテーブルを参照するすべての列を返す例です。

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 2017年

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は、2つのシステムでトップの答えが異なる結果になります。1つは外部キーテーブルの列名を示し、もう1つは主キーテーブルの列名を示します。このため、代わりにKEY_COLUMN_USAGEビューを使用することにしました。


情報スキーマは正しい答えのようですが、実際にはpg_catalogテーブルが必要です:pg_constraintなど。データベースに大量の制約がある場合、パフォーマンスの問題が発生する可能性があります...
hajikelist 2018年

上記の条件ORDINAL_POSITIONは、外部キーの列の順序が一意性制約の列の順序と異なる場合、誤った結果をもたらす可能性があります。私はあなたが上で参加しているべきだと考えkcu_foreign.POSITION_IN_UNIQUE_CONSTRAINT = kcu_primary.ORDINAL_POSITION アップデート:また、外部キーは、同様にUNIQUE制約に依存してもよい、私はあなたが削除すべきだと思うので、pks.CONSTRAINT_TYPE条件を、ちょうど参加することができますrckcu_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 2014

@pimlottc:bitbucket.org/reece/pgutilsに移動しました。これを指摘してくれてありがとう。
2014


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.