Migrations
Learn how to manage database migrations with Drizzle.
Migrations are a way to version control your database schema changes. They allow you to track, apply, and rollback database changes in a controlled and reproducible manner.
Migration Workflow
The typical migration workflow consists of three steps:
1. Generate Migration
After updating your schema files, generate a migration:
npm run db:generateThis command:
- Analyzes your schema files in
lib/db/schema/ - Compares them with the current database state
- Generates SQL migration files in
lib/db/migrations/ - Creates a migration metadata file
Migration Files
Migration files are stored in lib/db/migrations/ and should be
committed to version control. Each migration has a unique name and contains
the SQL statements needed to apply the changes.
2. Review Migration
Before applying, review the generated migration file to ensure it contains the expected changes:
ALTER TABLE "users" ADD COLUMN "phone" varchar(32);You can edit the migration file if needed, but be careful - only modify the SQL if you understand the implications.
3. Apply Migration
To apply the migration to your database, run:
npm run db:migrateThis command:
- Executes the migration SQL against your database
- Updates the migration history table
- Ensures your database schema matches your code
Migration Commands
Generate Migration
Generate a new migration from schema changes:
npm run db:generateThis creates migration files but doesn't apply them to the database.
Apply Migration
Apply pending migrations to the database:
npm run db:migrateThis runs all pending migrations in order.
Push Changes (Development Only)
For rapid prototyping, push schema changes directly without creating a migration:
npm run db:pushWarning
db:push is useful for development but should not be used in
production. Always use migrations (db:generate and
db:migrate) for production deployments.
Regenerate Migrations
If you need to regenerate migrations (e.g., after restoring from a backup):
npm run db:regenerateThis restores the migration files from the main branch and regenerates new migrations based on your current schema.
Production Migrations
For production deployments, follow these steps:
- Generate migrations locally - Run
npm run db:generateafter schema changes - Review migrations - Check the generated SQL files
- Test on staging - Apply migrations to a staging database first
- Commit migrations - Commit migration files to version control
- Deploy - Run
npm run db:migrateas part of your deployment process
Best Practice Always test migrations on a staging database that mirrors production before deploying to production.
Migration Best Practices
- Always generate migrations for production deployments
- Review migration files before applying them
- Test migrations on a staging database first
- Commit migration files to version control
- Never edit existing migrations - create new ones instead
- Use descriptive migration names - The migration name should describe what it does
- Keep migrations small - Break large changes into multiple migrations
- Don't delete migrations - Even if you rollback, keep the migration files
Migration History
Drizzle tracks migration history in a special table. You can view which migrations have been applied by checking your database.
The migration history table stores:
- Migration name
- Applied timestamp
- Migration SQL
Troubleshooting
Migration Fails
If a migration fails:
- Check the error message - It usually indicates what went wrong
- Review the migration SQL - Ensure the SQL is correct
- Check database state - Verify the current database schema
- Fix the migration - Edit the migration file if needed
- Re-run - Try applying the migration again
Migration Already Applied
If you see an error that a migration is already applied:
- Check migration history - Verify which migrations have been applied
- Skip if safe - If the migration was already applied, you can skip it
- Regenerate if needed - Use
npm run db:regenerateif migrations are out of sync
Schema Out of Sync
If your schema files don't match your database:
- Review schema files - Ensure they're up to date
- Check migration history - See which migrations have been applied
- Generate new migration - Run
npm run db:generateto create a migration that brings the database in sync - Apply migration - Run
npm run db:migrateto apply the changes
Advanced Topics
Custom Migration SQL
You can write custom SQL in migration files for complex changes:
-- Custom migration SQL
ALTER TABLE "users" ADD COLUMN "full_name" varchar(255);
UPDATE "users" SET "full_name" = "name" || ' ' || "last_name";Data Migrations
Migrations can also include data transformations:
-- Data migration example
UPDATE "users" SET "status" = 'active' WHERE "status" IS NULL;Rollback Migrations
While Drizzle doesn't have built-in rollback support, you can:
- Create a new migration - Write a migration that reverses the changes
- Manual rollback - Manually revert the database changes
- Restore from backup - Restore the database to a previous state
Migration Files Structure
Migration files are organized as follows:
lib/db/migrations/
├── meta/
│ ├── _journal.json # Migration journal
│ └── 0000_snapshot.json # Schema snapshot
├── 0001_initial.sql # Initial migration
├── 0002_add_users.sql # Add users table
└── 0003_add_phone_field.sql # Add phone fieldEach migration file contains the SQL needed to apply that specific change.