ALTER TABLE … ADD COLUMN creates a new column in an existing PostgreSQL table without rewriting unaffected data.
Add new attributes to a live table without downtime, enabling feature releases and analytics enhancements.
Use ALTER TABLE table_name ADD [COLUMN] column_name data_type [constraint] [options];
to append a column. Omitting COLUMN is allowed.
Any valid PostgreSQL type (text, numeric, jsonb, etc.). Choose defaults carefully to avoid table rewrites.
ALTER TABLE Customers ADD COLUMN phone text;
executes instantly because NULL needs no storage.
Phase it: add column nullable, backfill, then attach the DEFAULT to prevent full-table rewrite on large tables.
ALTER TABLE Orders ADD COLUMN status text; UPDATE Orders SET status = 'pending'; ALTER TABLE Orders ALTER COLUMN status SET DEFAULT 'pending' NOT NULL;
Yes. ALTER TABLE Products ADD COLUMN weight numeric, ADD COLUMN color text;
Add a delivered_at timestamp to Orders to track fulfillment.
ALTER TABLE Orders
ADD COLUMN delivered_at timestamptz;
\d+ Orders
in psql or query information_schema.columns
.
1. Always qualify table names in multi-schema setups.
2. Use transactions to bundle schema and data changes.
3. Communicate changes via migration files and code reviews.
Forgetting to backfill before NOT NULL – leads to immediate error. Backfill first.
Applying DEFAULT on huge tables – causes rewrite and locking. Use phased approach.
Run ALTER TABLE … DROP COLUMN
inside the same transaction if still pending. Otherwise create a new migration to remove it.
Only when adding a NOT NULL column with a non-null default; PostgreSQL rewrites every row. Plan maintenance windows for large tables.
Grant ALTER
privilege cautiously. Use role-based access to limit who can change schemas.
Only if a full rewrite is needed (NOT NULL with default). Simple nullable adds are almost instant.
Yes. ALTER TABLE Orders ADD COLUMN customer_id integer REFERENCES Customers(id);
Run ALTER TABLE on the parent partitioned table; PostgreSQL propagates the new column to partitions.