1.4 KiB
1.4 KiB
Database Migration Strategy
Drizzle ORM Migrations
Development (Local / Test)
Use db:push for rapid iteration:
bun run db:push
This syncs schema directly — fast but destructive. Fine for dev/test.
Production
Use db:migrate with generated migration files:
bun run db:generate # creates SQL migration file
bun run db:migrate # applies migration
Workflow
- Change schema in
src/db/schema.ts - Run
bun run db:generate— creates migration indrizzle/ - Review the generated SQL
- Write rollback SQL in
drizzle/rollback/(same filename) - Test migration on staging
- Apply to production
Safe Migration Practices
Adding columns
- Always add as nullable or with a default value
- Never add non-nullable columns without defaults to tables with existing data
Removing columns
- First deploy: stop reading/writing the column in code
- Second deploy: remove the column from schema
- Two-phase approach prevents errors during rolling deploys
Renaming columns
- Don't rename directly — add new column, migrate data, remove old column
Adding indexes
- Use
CREATE INDEX CONCURRENTLYfor large tables (avoids locks) - Drizzle may not generate concurrent indexes — check generated SQL
Backup Before Migration
Always backup before production migrations:
pg_dump -Fc $DATABASE_URL > backup-$(date +%Y%m%d-%H%M%S).dump