如何列出PostgreSQL中表的所有约束?

问题描述 投票:0回答:6

如何列出 PostgreSQL 中表的所有约束(主键、外键、检查、唯一互斥、..)?

postgresql constraints
6个回答
35
投票

可以使用 SELECT 查询从

catalog-pg-constraint 检索表的约束。

SELECT con.* FROM pg_catalog.pg_constraint con INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace WHERE nsp.nspname = '{schema name}' AND rel.relname = '{table name}';
并且可以使用

PSQL
中查看相同内容

\d+ {SCHEMA_NAME.TABLE_NAME}
    

11
投票

这是 POSTGRES 具体答案 .....它将检索所有列及其关系

SELECT * FROM ( SELECT pgc.contype as constraint_type, pgc.conname as constraint_name, ccu.table_schema AS table_schema, kcu.table_name as table_name, CASE WHEN (pgc.contype = 'f') THEN kcu.COLUMN_NAME ELSE ccu.COLUMN_NAME END as column_name, CASE WHEN (pgc.contype = 'f') THEN ccu.TABLE_NAME ELSE (null) END as reference_table, CASE WHEN (pgc.contype = 'f') THEN ccu.COLUMN_NAME ELSE (null) END as reference_col, CASE WHEN (pgc.contype = 'p') THEN 'yes' ELSE 'no' END as auto_inc, CASE WHEN (pgc.contype = 'p') THEN 'NO' ELSE 'YES' END as is_nullable, 'integer' as data_type, '0' as numeric_scale, '32' as numeric_precision FROM pg_constraint AS pgc JOIN pg_namespace nsp ON nsp.oid = pgc.connamespace JOIN pg_class cls ON pgc.conrelid = cls.oid JOIN information_schema.key_column_usage kcu ON kcu.constraint_name = pgc.conname LEFT JOIN information_schema.constraint_column_usage ccu ON pgc.conname = ccu.CONSTRAINT_NAME AND nsp.nspname = ccu.CONSTRAINT_SCHEMA UNION SELECT null as constraint_type , null as constraint_name , 'public' as "table_schema" , table_name , column_name, null as refrence_table , null as refrence_col , 'no' as auto_inc , is_nullable , data_type, numeric_scale , numeric_precision FROM information_schema.columns cols Where 1=1 AND table_schema = 'public' and column_name not in( SELECT CASE WHEN (pgc.contype = 'f') THEN kcu.COLUMN_NAME ELSE kcu.COLUMN_NAME END FROM pg_constraint AS pgc JOIN pg_namespace nsp ON nsp.oid = pgc.connamespace JOIN pg_class cls ON pgc.conrelid = cls.oid JOIN information_schema.key_column_usage kcu ON kcu.constraint_name = pgc.conname LEFT JOIN information_schema.constraint_column_usage ccu ON pgc.conname = ccu.CONSTRAINT_NAME AND nsp.nspname = ccu.CONSTRAINT_SCHEMA ) ) as foo ORDER BY table_name desc
    

9
投票
这是获取 PostgreSQL 中表的所有约束的简单方法

SELECT constraint_name, table_name, column_name, ordinal_position FROM information_schema.key_column_usage WHERE table_name = '<your_table_name>';
    

7
投票
我无法使上述解决方案发挥作用。 也许他们不再受到支持,或者更有可能是我做错了什么。 这就是我让它发挥作用的方式。 请注意,“contype”列将缩写为约束类型(例如,“c”表示检查,“p”表示主键等)。 我包含该变量,以防您想在 FROM 块之后添加 WHERE 语句来过滤它。

select pgc.conname as constraint_name, ccu.table_schema as table_schema, ccu.table_name, ccu.column_name, contype, pg_get_constraintdef(pgc.oid) from pg_constraint pgc join pg_namespace nsp on nsp.oid = pgc.connamespace join pg_class cls on pgc.conrelid = cls.oid left join information_schema.constraint_column_usage ccu on pgc.conname = ccu.constraint_name and nsp.nspname = ccu.constraint_schema order by pgc.conname;
    

0
投票
这适用于当您想要获取

列名称+约束定义,按架构+表过滤。有点解决方法,但有效。

SELECT SUBSTRING( pg_get_constraintdef(con.oid) FROM 7 ) as "check_definition", (REGEXP_MATCHES( SUBSTRING(pg_get_constraintdef(con.oid) FROM 7), 'length\("([^"]+)"\)' ))[1] as "column_name" FROM pg_catalog.pg_constraint con INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace WHERE nsp.nspname = 'my_schema' AND rel.relname = 'my_table' AND contype = 'c'; --only "check" constraints
| check_definition                                                                | column_name        |
|---------------------------------------------------------------------------------|--------------------|
| (((length("User_Name") > 0) AND (length("User_Name") < 250)))                   | User_Name          |
| (((length("User_AccountNumber") > 0) AND (length("User_AccountNumber") < 250))) | User_AccountNumber |
| (((length("User_FirstName") > 0) AND (length("User_FirstName") < 250)))         | User_FirstName     |
| (((length("User_LastName") > 0) AND (length("User_LastName") < 250)))           | User_LastName      |
| (((length("User_PersonalEmail") > 0) AND (length("User_PersonalEmail") < 250))) | User_PersonalEmail |
| (((length("User_Phone") > 0) AND (length("User_Phone") < 250)))                 | User_Phone         |
| (((length("User_PlaceOfBirth") > 0) AND (length("User_PlaceOfBirth") < 250)))   | User_PlaceOfBirth  |
| (((length("User_WorkEmail") > 0) AND (length("User_WorkEmail") < 250)))         | User_WorkEmail     |
我的正则表达式假设在“文本长度约束”中查找列名称,结构类似于 

(((length("User_Name") > 0) AND (length("User_Name") < 250)))


    


0
投票
要动态生成创建具有所有约束的表的 PostgreSQL 脚本,您可以查询 PostgreSQL 系统目录表 (pg_catalog) 以提取有关列、主键、外键和检查约束的信息。

这是动态生成 CREATE TABLE 语句的完整脚本:

DO $$ DECLARE schema_name TEXT := 'public'; -- Replace with your schema name table_name TEXT := 'employees'; -- Replace with your table name column_def RECORD; pk_constraint RECORD; fk_constraint RECORD; check_constraint RECORD; create_table_query TEXT := ''; BEGIN -- Start CREATE TABLE statement create_table_query := format('CREATE TABLE IF NOT EXISTS %I.%I (\n', schema_name, table_name); -- Add columns FOR column_def IN EXECUTE format( 'SELECT column_name, data_type, character_maximum_length, numeric_precision, numeric_scale, is_nullable, column_default FROM information_schema.columns WHERE table_schema = %L AND table_name = %L', schema_name, table_name ) LOOP create_table_query := create_table_query || format(' %I %s%s%s%s,\n', column_def.column_name, CASE WHEN column_def.data_type = 'character varying' THEN format('character varying(%s)', column_def.character_maximum_length) WHEN column_def.data_type = 'numeric' THEN format('numeric(%s, %s)', column_def.numeric_precision, column_def.numeric_scale) ELSE column_def.data_type END, CASE WHEN column_def.is_nullable = 'NO' THEN ' NOT NULL' ELSE '' END, CASE WHEN column_def.column_default IS NOT NULL THEN format(' DEFAULT %s', column_def.column_default) ELSE '' END, CASE WHEN column_def.data_type = 'character varying' THEN ' COLLATE pg_catalog."default"' ELSE '' END ); END LOOP; -- Add primary key constraint FOR pk_constraint IN EXECUTE format( 'SELECT conname, pg_get_constraintdef(oid, true) AS definition FROM pg_constraint WHERE conrelid = %L::regclass AND contype = %L', format('%I.%I', schema_name, table_name), 'p' -- 'p' = Primary Key ) LOOP create_table_query := create_table_query || format(' CONSTRAINT %I %s,\n', pk_constraint.conname, pk_constraint.definition); END LOOP; -- Add foreign key constraints FOR fk_constraint IN EXECUTE format( 'SELECT conname, pg_get_constraintdef(oid, true) AS definition FROM pg_constraint WHERE conrelid = %L::regclass AND contype = %L', format('%I.%I', schema_name, table_name), 'f' -- 'f' = Foreign Key ) LOOP create_table_query := create_table_query || format(' CONSTRAINT %I %s,\n', fk_constraint.conname, fk_constraint.definition); END LOOP; -- Add check constraints FOR check_constraint IN EXECUTE format( 'SELECT conname, pg_get_constraintdef(oid, true) AS definition FROM pg_constraint WHERE conrelid = %L::regclass AND contype = %L', format('%I.%I', schema_name, table_name), 'c' -- 'c' = Check Constraint ) LOOP create_table_query := create_table_query || format(' CONSTRAINT %I %s,\n', check_constraint.conname, check_constraint.definition); END LOOP; -- Remove last comma and close the statement create_table_query := regexp_replace(create_table_query, ',\n$', '\n'); create_table_query := create_table_query || ');'; -- Print the generated query RAISE NOTICE '%', create_table_query; END $$;
    
© www.soinside.com 2019 - 2024. All rights reserved.