Raypx

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

Commands Reference

All database commands are run from the project root via Turborepo:

CommandDescription
pnpm db:pushPush schema changes directly to the database (dev only).
pnpm db:generateGenerate SQL migration files from schema changes.
pnpm db:migrateApply all pending migrations to the database.
pnpm db:studioOpen Drizzle Studio (database GUI) in the browser.
pnpm db:pullPull the current database schema into Drizzle schema files (reverse engineering).

Drizzle Kit Configuration

The configuration is in packages/database/drizzle.config.ts:

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 in packages/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:

packages/database/src/migrate.ts
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:studio

This 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:

  1. Manually write a "down" migration SQL file that reverses the changes.
  2. Apply it with pnpm db:migrate.
  3. Delete the corresponding "up" migration file from packages/database/migrations/.
  4. Remove the migration record from the __drizzle_migrations table.

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 migrations

The meta/_journal.json file maintains the order and status of all migrations. Drizzle Kit uses this to determine which migrations are pending.

On this page