Migrations
Database migration workflow with Drizzle Kit.
Raypx uses Drizzle Kit for database migrations. Drizzle Kit reads your schema definitions and generates SQL migration files that can be applied to your database.
Development vs Production
Use db:push during development. This synchronizes your schema directly to the database without generating migration files. It is fast and convenient for iterating on your schema.
pnpm db:pushdb:push does not generate migration files. Changes are applied directly and cannot be version-controlled or rolled back. Only use this in development.
Use db:generate and db:migrate for production deployments. This generates SQL migration files that you can review, commit, and apply in a controlled manner.
# Generate migration files from schema changes
pnpm db:generate
# Apply pending migrations
pnpm db:migrateCommands Reference
All database commands are run from the project root via Turborepo:
| Command | Description |
|---|---|
pnpm db:push | Push schema changes directly to the database (dev only). |
pnpm db:generate | Generate SQL migration files from schema changes. |
pnpm db:migrate | Apply all pending migrations to the database. |
pnpm db:studio | Open Drizzle Studio (database GUI) in the browser. |
pnpm db:pull | Pull the current database schema into Drizzle schema files (reverse engineering). |
Drizzle Kit Configuration
The configuration is in packages/database/drizzle.config.ts:
import { defineConfig } from "drizzle-kit"
export default defineConfig({
schema: "./src/schema/index.ts",
out: "./migrations",
dialect: "postgresql",
dbCredentials: {
url: process.env.DATABASE_URL,
},
casing: "snake_case",
verbose: true,
strict: true,
schemaFilter: ["public.*", "public"],
migrations: {
table: "__drizzle_migrations",
schema: "public",
},
})Key settings:
schema-- Points to the schema entry file that re-exports all tables.out-- Migration files are generated inpackages/database/migrations/.casing: "snake_case"-- Column names are automatically converted to snake_case.strict: true-- Warns about potential data loss in migrations.
Migration Workflow
Edit files in packages/database/src/schema/. Add tables, columns, or modify existing ones.
Run pnpm db:generate. Drizzle Kit compares the current schema with the database and generates a SQL migration file in packages/database/migrations/.
Open the generated .sql file and verify the changes are correct. Look for unexpected DROP or ALTER statements.
Run pnpm db:migrate to apply the pending migration to your database. Migrations are tracked in the __drizzle_migrations table.
Running Migrations in Docker
In production deployments, you can run migrations as part of your container startup. The @raypx/database package exports a runMigrations function:
import { migrate } from "drizzle-orm/postgres-js/migrator"
import { createDb } from "./client"
export async function runMigrations() {
const db = createDb()
await migrate(db, { migrationsFolder: "./migrations" })
}You can call this from your server entry point before starting the application.
Drizzle Studio
Drizzle Studio provides a web-based GUI for browsing and editing your database:
pnpm db:studioThis opens an interactive interface in your browser where you can:
- Browse all tables and their data.
- Edit rows directly.
- Run custom SQL queries.
- View table relationships.
Rollback Strategy
Drizzle Kit does not have a built-in rollback command. To roll back a migration:
- Manually write a "down" migration SQL file that reverses the changes.
- Apply it with
pnpm db:migrate. - Delete the corresponding "up" migration file from
packages/database/migrations/. - Remove the migration record from the
__drizzle_migrationstable.
For critical production databases, always back up your data before applying migrations. Consider using PostgreSQL's pg_dump for full backups.
Migration Files
Generated migration files are stored in packages/database/migrations/ and follow this structure:
migrations/
0000_initial_migration.sql
0001_add_profiles_table.sql
0002_add_conversations.sql
...
meta/
_journal.json # Tracks applied migrationsThe meta/_journal.json file maintains the order and status of all migrations. Drizzle Kit uses this to determine which migrations are pending.