I need a query that returns:
“table_name”, “field_name”, “field_type”, “contraint_name”
until now i have:
select conrelid::regclass AS table_name, regexp_replace(pg_get_constraintdef(c.oid), '.*((.*))', '1') as fields, conname as contraint_name from pg_constraint c join pg_namespace n ON n.oid = c.connamespace join pg_attribute at on --join pg_type t ON t.typnamespace = n.oid where contype ='f'
Advertisement
Answer
A foreign key may be based on multiple columns, so conkey
and confkey
of pg_constraint
are arrays. You have to unnest the arrays to get a list of column names or types. You can use these functions:
create or replace function get_col_names(rel regclass, cols int2[]) returns text language sql as $$ select string_agg(attname, ', ' order by ordinality) from pg_attribute, unnest(cols) with ordinality where attrelid = rel and attnum = unnest $$; create or replace function get_col_types(rel regclass, cols int2[]) returns text language sql as $$ select string_agg(typname, ', ' order by ordinality) from pg_attribute a join pg_type t on t.oid = atttypid, unnest(cols) with ordinality where attrelid = rel and attnum = unnest $$;
The functions may be very handy when querying constraints and indexes. Your query is nice and simple with them:
select conrelid::regclass, get_col_names(conrelid, conkey) col_names, get_col_types(conrelid, conkey) col_types, conname from pg_constraint where contype ='f'; conrelid | col_names | col_types | conname ----------+-----------+-----------+------------------------ products | image_id | int4 | products_image_id_fkey (1 row)