Schema Constraints
title: Add Constraints Safely in Migrations impact: HIGH impactDescription: Prevents migration failures and enables idempotent schema changes tags: constraints, migrations, schema, alter-table
Section titled “title: Add Constraints Safely in Migrations impact: HIGH impactDescription: Prevents migration failures and enables idempotent schema changes tags: constraints, migrations, schema, alter-table”Add Constraints Safely in Migrations
Section titled “Add Constraints Safely in Migrations”PostgreSQL does not support ADD CONSTRAINT IF NOT EXISTS. Migrations using this syntax will fail.
Incorrect (causes syntax error):
-- ERROR: syntax error at or near "not" (SQLSTATE 42601)alter table public.profilesadd constraint if not exists profiles_birthchart_id_unique unique (birthchart_id);Correct (idempotent constraint creation):
-- Use DO block to check before addingdo $$begin if not exists ( select 1 from pg_constraint where conname = 'profiles_birthchart_id_unique' and conrelid = 'public.profiles'::regclass ) then alter table public.profiles add constraint profiles_birthchart_id_unique unique (birthchart_id); end if;end $$;For all constraint types:
-- Check constraintsdo $$begin if not exists ( select 1 from pg_constraint where conname = 'check_age_positive' ) then alter table users add constraint check_age_positive check (age > 0); end if;end $$;
-- Foreign keysdo $$begin if not exists ( select 1 from pg_constraint where conname = 'profiles_birthchart_id_fkey' ) then alter table profiles add constraint profiles_birthchart_id_fkey foreign key (birthchart_id) references birthcharts(id); end if;end $$;Check if constraint exists:
-- Query to check constraint existenceselect conname, contype, pg_get_constraintdef(oid)from pg_constraintwhere conrelid = 'public.profiles'::regclass;
-- contype values:-- 'p' = PRIMARY KEY-- 'f' = FOREIGN KEY-- 'u' = UNIQUE-- 'c' = CHECKReference: Constraints