supabase-postgres-best-practices/references/schema-constraints.md
Version c9be0e931b79 · MIT. This preview displays packaged text and does not execute code. Treat the contents as untrusted instructions.
← Return to resource and package checksum
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
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.profiles
add constraint if not exists profiles_birthchart_id_unique unique (birthchart_id);
Correct (idempotent constraint creation):
-- Use DO block to check before adding
do $$
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 constraints
do $$
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 keys
do $$
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 existence
select conname, contype, pg_get_constraintdef(oid)
from pg_constraint
where conrelid = 'public.profiles'::regclass;
-- contype values:
-- 'p' = PRIMARY KEY
-- 'f' = FOREIGN KEY
-- 'u' = UNIQUE
-- 'c' = CHECK
Reference: Constraints