Postgres9.4では、特定のテーブルのUNIQUE
制約に関係するすべての列の名前をプルしようとしていますPostgres。
そのような列の名前はpg_constraint
に含まれているようです。 ドキュメント によると、私の問題に関連する列はconkey
と呼ばれ、たまたまint
sの配列です。
ポイントは、私が思いついたクエリは私に間違った結果を与えており、私はconkey
に間違った方法で参加しているためだと確信しています。クエリは次のとおりです。
SELECT
pg_attribute.attname,
pg_constraint.*
FROM
pg_attribute
INNER JOIN pg_constraint
ON pg_attribute.attnum = ANY (pg_constraint.conkey)
WHERE pg_constraint.conrelid = (
SELECT
oid
FROM
pg_class
WHERE
relname LIKE 'test_table'
)
AND pg_constraint.contype = 'u'; -- to filter out non-unique constraints
以下は、簡単な再現のためのテーブルDDLです。
CREATE TABLE "test_table" (
"date" date DEFAULT now() NOT NULL,
"foo" varchar COLLATE "default" NOT NULL
CONSTRAINT "test_table_foo_key" UNIQUE ("foo")
)
WITH (OIDS=FALSE);
ALTER TABLE "test_table" OWNER TO "postgres";
今、誰かが私が間違っていることを教えてもらえますか?必要な情報をまとめて入手する簡単な方法はありますか?
私が書いているアプリはPostgresでのUPSERT
の現在の欠如を回避する必要があるので、制約付きテーブルの名前を取得しようとしています。アイデアは、CTEを使用して挿入または更新を行うことですが、制約された列が事前に何であるかがわからないため、このビットのイントロスペクションを行う必要があります。
2つのテーブル間の接続が半分失われます。 ...relid
列も一致する必要があります:
SELECT attname, c.*
FROM pg_attribute a
JOIN pg_constraint c
ON attrelid = conrelid -- this was missing
AND attnum = ANY (conkey)
WHERE attrelid = 'test_table'::regclass;