Search code examples
sqlpostgresqlsystem-views

List all foreign keys PostgreSQL


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' 

Solution

  • 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)