Development vs Production
Development: db:push
Quick schema updates without migration files - perfect for rapid iteration
Production: Migrations
Versioned migration files for controlled, trackable schema changes
Available Commands
All database commands are defined inpackage.json:
package.json
db:push
Pushes your schema directly to the database without creating migration files.When to use: Development only. Use this for rapid prototyping and local development when you want instant schema updates.
- Compares your
src/db/schema.tswith the current database state - Generates and executes SQL to sync the database
- Does NOT create migration files
- Cannot be rolled back
db:generate
Generates SQL migration files from schema changes.When to use: Production deployments. Creates versioned migration files that can be committed to version control.
- Compares your
src/db/schema.tswith the last migration snapshot - Generates SQL migration files in
src/db/migrations/ - Creates a
meta/folder with migration metadata - Does NOT execute the migration
db:migrate
Executes pending migration files against the database.When to use: After running
db:generate, or when deploying to production.- Reads migration files from
src/db/migrations/ - Executes any pending migrations in order
- Tracks which migrations have been applied
- Can be run multiple times safely (idempotent)
db:studio
Opens Drizzle Studio - a visual database browser.- Launches a web interface at
https://local.drizzle.studio - Allows you to browse tables and data
- Supports editing records directly
- Useful for debugging and data inspection
Migration Workflows
Development Workflow (db:push)
For rapid local development:Production Workflow (Migrations)
For production-ready deployments:Review migration SQL
Open the generated
.sql file and verify the migration logic:src/db/migrations/0001_add_post_table.sql
When to Use Each Approach
- Use db:push
- Use Migrations
Development scenarios:
- Local development and prototyping
- Experimenting with schema designs
- Personal projects without team collaboration
- When you don’t need migration history
- Instant feedback
- No migration files to manage
- Perfect for rapid iteration
- No rollback capability
- No migration history
- Can’t track what changed when
Migration Best Practices
Always review generated SQL
Always review generated SQL
Before running migrations in production, open the generated
.sql file and verify:- The SQL does what you expect
- Foreign keys are correct
- Indexes are created where needed
- Data migrations won’t cause data loss
Test migrations locally first
Test migrations locally first
Commit migrations with schema changes
Commit migrations with schema changes
Run migrations in CI/CD
Run migrations in CI/CD
Add to your deployment pipeline:
.github/workflows/deploy.yml
Backup before production migrations
Backup before production migrations
Always backup your production database before applying migrations:
Troubleshooting
Migration fails with 'relation already exists'
Migration fails with 'relation already exists'
This usually means your database state doesn’t match the migration history.Solution:
- For development: Drop the database and re-run all migrations
- For production: Manually adjust the migration or database state
db:push shows no changes but schema is different
db:push shows no changes but schema is different
Drizzle may not detect certain changes automatically.Solution:
- Use migrations instead of push for complex changes
- Verify your schema syntax is correct
Cannot connect to database
Cannot connect to database
Check your
DATABASE_URL environment variable.Solution:Next Steps
Adding Tables
Learn how to add custom tables to your schema
Schema Reference
View the complete database schema
Drizzle Docs
Official migration documentation