List Foreign Key Constraints in PostgreSQL
List Foreign Key Constraints in PostgreSQL
Foreign key constraints enforce referential integrity between tables. They guarantee that a value in one table's column always has a matching row in another table. Knowing which foreign keys exist — and how they are defined — is essential before dropping tables, renaming columns, or loading large datasets.
This SQL query lists every foreign key in the public schema, showing the table that owns the constraint, the constraint name, and the full constraint definition including which columns it spans and which table it references.
SQL Script
1SELECT conrelid::regclass AS table_name,
2 conname AS foreign_key,
3 pg_get_constraintdef(oid)
4FROM pg_constraint
5WHERE contype = 'f'
6AND connamespace = 'public'::regnamespace
7ORDER BY conrelid::regclass::text, contype DESC;
Notes: Works on PostgreSQL 9.1 and later. Queries pg_constraint directly, which is faster and more complete than querying information_schema. Results are limited to the public schema — change 'public'::regnamespace to audit a different schema.
Code Breakdown
pg_constraint
The pg_constraint system catalog stores every constraint defined in the database: primary keys, unique constraints, check constraints, exclusion constraints, and foreign keys. Each row is one constraint.
contype = 'f'
Filters to foreign key constraints only. The constraint type codes are: p (primary key), u (unique), c (check), x (exclusion), and f (foreign key).
conrelid::regclass AS table_name
conrelid is the OID of the table that owns the constraint. Casting it to regclass converts the OID to a human-readable schema-qualified table name automatically.
conname AS foreign_key
The constraint name as assigned at creation time, or the name PostgreSQL generated automatically. Auto-generated names follow the pattern tablename_columnname_fkey.
pg_get_constraintdef(oid)
A built-in PostgreSQL function that returns the full DDL definition of a constraint as a text string. For a foreign key, this includes the column list, the referenced table, the referenced column list, and any ON DELETE or ON UPDATE actions defined.
connamespace = 'public'::regnamespace
Limits results to constraints in the public schema. Replace 'public' with any schema name to audit that schema instead.
ORDER BY conrelid::regclass::text, contype DESC
Sorts by table name alphabetically so that all foreign keys on the same table appear together.
Key Points
- Each row is one foreign key constraint. A table with multiple foreign keys produces multiple rows.
- The
pg_get_constraintdefoutput shows the exact SQL definition, including referenced columns and any cascade or restrict actions. - The query covers only the public schema by default. Remove the namespace filter entirely to audit all schemas.
- An empty result set means the public schema has no foreign key constraints defined.
Insights and Explanations
Foreign key constraints affect several common DBA tasks:
- Dropping a table: PostgreSQL will refuse to drop a table that is referenced by a foreign key in another table unless you use
CASCADEor drop the referencing constraint first. This query shows you which tables reference the one you want to drop. - Bulk data loads: Foreign key checks run on every inserted row. Disabling foreign key checks during a large load can dramatically reduce load time, but you must verify integrity afterward.
- Column renames: Renaming a column that is part of a foreign key requires understanding the dependencies. Check this query before renaming columns.
The pg_get_constraintdef output will include ON DELETE CASCADE, ON DELETE SET NULL, ON UPDATE RESTRICT, or similar clauses if they were defined. A cascade action will silently delete rows in child tables when a parent row is removed.
If referential integrity was not enforced historically, there may be orphaned rows in child tables. After identifying your foreign keys, check for orphans:
1-- Find rows in child_table with no matching parent
2SELECT c.*
3FROM child_table c
4LEFT JOIN parent_table p ON p.id = c.parent_id
5WHERE p.id IS NULL;
Additional Considerations
- Permissions: Any user can query
pg_constraint. No superuser access is required to list constraints. - Performance: The query reads only system catalog tables and is instantaneous regardless of data volume.
- All schemas: To list foreign keys across all user schemas, remove the
connamespacefilter and addconnamespaceto the SELECT list to identify which schema each constraint belongs to. - information_schema alternative:
information_schema.referential_constraintsprovides similar information in a portable SQL-standard format, butpg_constraintwithpg_get_constraintdefreturns the complete definition in a single readable line.
References
Posts in this series
- How Many Connections Can Your PostgreSQL Database Handle?
- PostgreSQL Backend Connections via pg_stat_database
- Identifying Blocking PostgreSQL Queries using pg_stat_activity
- List PostgreSQL Databases by Size with Access Check
- Assess PostgreSQL Database Sizes Quickly and Easily
- Unveiling Your PostgreSQL Server - A Diagnostic Powerhouse
- Keep Your PostgreSQL Database Clean, Identify Idle Connections
- Query the PostgreSQL Configuration
- PostgreSQL Recovery Monitoring: Essential SQL Insights
- Restart All PostgreSQL Sequences with ALTER SEQUENCE
- Monitor Running Queries in PostgreSQL using pg_stat_activity
- Monitor PostgreSQL Active Sessions with pg_stat_activity
- PostgreSQL Error Handling Settings via pg_settings
- PostgreSQL File Location Settings Query via pg_settings
- PostgreSQL Lock Management Settings via pg_settings
- PostgreSQL Logging Configuration Query via pg_settings
- Monitor PostgreSQL Memory Settings with pg_settings
- PostgreSQL Table Row Count Estimates with SQL
- List PostgreSQL Tables by Size with SQL
- PostgreSQL WAL Settings Query Guide
- PostgreSQL SSL Settings Query Guide
- PostgreSQL Statistics Settings Query Guide
- PostgreSQL Resource Settings Query Guide
- PostgreSQL Replication Settings Query Guide
- PostgreSQL Query Planning Settings Query Guide
- PostgreSQL Preset Options Settings Query Guide
- PostgreSQL Miscellaneous Settings Query Guide
- Count PostgreSQL Sessions by State with SQL
- Kill Idle PostgreSQL Sessions with SQL
- Grant SELECT on All Tables in PostgreSQL
- Identify Insert-Only Tables in PostgreSQL
- Detect Soft Delete Patterns in PostgreSQL
- List PostgreSQL Object Comments with SQL
- List Foreign Key Constraints in PostgreSQL
- List PostgreSQL Enum Types and Their Values with SQL
- List All Views in a PostgreSQL Database with SQL
- Find PostgreSQL Tables Without a Primary Key
- List PostgreSQL Partitioned Tables with SQL