09 - Migrations

📋 Jump to Takeaways

Drizzle Kit handles schema changes. It reads your TypeScript schema, compares it to the database, and generates SQL migration files. You choose between push for quick iteration and migrate for production safety.

Drizzle Config

Every project needs a drizzle.config.ts at the root.

import { defineConfig } from 'drizzle-kit';

export default defineConfig({
  schema: './src/db/schema.ts',
  out: './drizzle',
  dialect: 'postgresql',
  dbCredentials: {
    url: process.env.DATABASE_URL!
  }
});

schema points to your table definitions. out is where migration files go. dialect matches your database.

Push vs Migrate

These are two different workflows. Pick one based on your situation.

Push

drizzle-kit push applies your schema directly to the database. No migration files. Fast and simple.

npx drizzle-kit push

Use push during local development when you are iterating on your schema and do not need a history of changes.

Migrate

drizzle-kit generate creates SQL migration files. drizzle-kit migrate runs them in order.

# Generate a migration from schema changes
npx drizzle-kit generate

# Apply pending migrations
npx drizzle-kit migrate

Use migrate in production. Migration files give you a versioned history, code review on schema changes, and rollback points.

❌ Using push in production:

# Dangerous: no history, no review, can drop data
npx drizzle-kit push

✅ Using generate + migrate in production:

npx drizzle-kit generate
# Review the generated SQL file
npx drizzle-kit migrate

Migration Files

Generated migrations live in your out directory. Each file has a timestamp and a SQL file.

drizzle/
├── 0000_initial.sql
├── 0001_add_posts_table.sql
├── 0002_add_user_role.sql
└── meta/
    └── _journal.json

The _journal.json tracks which migrations have run. Never edit it manually.

A migration file looks like plain SQL:

ALTER TABLE "users" ADD COLUMN "role" text DEFAULT 'user' NOT NULL;

Drizzle Studio

drizzle-kit studio opens a browser UI to view and edit your data.

npx drizzle-kit studio

Useful for inspecting data during development. Not a production tool.

Safe Schema Changes

Some changes are safe. Others can destroy data. Know the difference.

Adding a column

Safe. Add a default value to avoid breaking existing rows.

// In your schema
role: text('role').default('user').notNull()
npx drizzle-kit generate
# Generated SQL: ALTER TABLE "users" ADD COLUMN "role" text DEFAULT 'user' NOT NULL;

Renaming a column

Drizzle Kit may interpret a rename as a drop + add, which deletes data. Check the generated SQL carefully.

-- What you might expect:
ALTER TABLE "users" RENAME COLUMN "name" TO "full_name";

-- What Drizzle Kit might generate:
ALTER TABLE "users" DROP COLUMN "name";
ALTER TABLE "users" ADD COLUMN "full_name" text;

If the generated SQL drops and adds, edit the migration file manually to use RENAME COLUMN instead.

Dropping a column

Permanent data loss. Always back up first.

npx drizzle-kit generate
# Review the SQL before running
cat drizzle/0003_drop_legacy_field.sql
npx drizzle-kit migrate

Practical Workflow

A typical development cycle:

  1. Edit your schema in TypeScript
  2. Run npx drizzle-kit push locally to test
  3. When ready, run npx drizzle-kit generate to create a migration
  4. Review the generated SQL
  5. Commit the migration file
  6. In production, run npx drizzle-kit migrate
# Local development
npx drizzle-kit push

# Ready for production
npx drizzle-kit generate
git add drizzle/
git commit -m "add role column to users"

# Production deploy
npx drizzle-kit migrate

Key Takeaways

  • drizzle.config.ts defines your schema path, output directory, dialect, and database credentials
  • push applies schema directly; use it for local development only
  • generate creates versioned SQL files; migrate runs them in order
  • Always review generated SQL before applying, especially for renames and drops
  • Migration files are plain SQL and can be edited manually when needed
  • drizzle-kit studio provides a visual data browser for development
  • Never edit _journal.json manually

📝 Ready to test your knowledge?

Answer the quiz below to mark this lesson complete.

© 2026 ByteLearn.dev. Free courses for developers. · Privacy