Skip to main content

Overview

Autonome uses Drizzle Kit to manage database migrations. The workflow is:
  1. Edit schema: Modify src/db/schema.ts
  2. Generate migration: Run bun run db:generate
  3. Review SQL: Check generated migration in drizzle/ directory
  4. Apply migration: Run bun run db:migrate

Configuration

Drizzle Kit configuration is in drizzle.config.ts:
Key Settings:
  • dialect: PostgreSQL database
  • out: Migrations stored in drizzle/ directory
  • schema: Single source of truth at src/db/schema.ts
  • dbCredentials.url: Read from DATABASE_URL environment variable

Available Commands

All database commands are defined in package.json:

db:generate

Generate migration files from schema changes:
What it does:
  1. Compares src/db/schema.ts to current database state
  2. Generates SQL migration file in drizzle/ directory
  3. Creates a metadata file (.json) for tracking
Example output:
When to use:
  • After modifying tables, columns, or indexes in src/db/schema.ts
  • Before committing schema changes to Git

db:migrate

Apply pending migrations to the database:
What it does:
  1. Reads all migration files in drizzle/
  2. Checks which migrations have been applied (via __drizzle_migrations table)
  3. Applies pending migrations in order
Example output:
When to use:
  • After generating a new migration
  • On production deployment to sync database
  • When setting up a new development environment

db:push

Push schema changes directly to database (skip migration generation):
What it does:
  1. Compares src/db/schema.ts to database
  2. Applies changes directly without generating migration files
⚠️ Warning: Use only in development. This bypasses migration history. When to use:
  • Rapid prototyping in local development
  • Throwaway feature branches
  • Never on production

db:seed

Reset database and seed with default models:
What it does:
  1. Drops all tables
  2. Recreates schema
  3. Seeds with default AI models and variants
⚠️ Warning: Destructive operation. Only use in development.

db:studio

Launch Drizzle Studio (database GUI):
What it does:
  1. Starts local web server
  2. Opens browser at https://local.drizzle.studio
  3. Provides GUI for browsing/editing database data
When to use:
  • Debugging database state
  • Manual data inspection
  • Quick one-off updates

Migration Workflow

Step 1: Modify Schema

Edit src/db/schema.ts with your changes:

Step 2: Generate Migration

Review the generated SQL file in drizzle/:
Check for:
  • Correct column types
  • Proper table names (quoted if capitalized)
  • Safe default values (avoid breaking existing data)

Step 3: Apply Migration

Verify migration succeeded:

Step 4: Commit Changes

Always commit both:
  • src/db/schema.ts (TypeScript schema)
  • drizzle/XXXX_*.sql (generated SQL migration)

Common Migration Scenarios

Adding a Column

Then:

Adding a Required Column with Default

Why default? Existing rows need a value for NOT NULL columns.

Renaming a Column

Drizzle cannot detect renames automatically. You must:
  1. Generate SQL for new column:
  2. Manually edit migration:
  3. Apply migration:

Dropping a Column

Then:
⚠️ Warning: Data loss is permanent. Consider:
  1. Backing up data first
  2. Using a two-step migration (make nullable → drop later)

Adding an Index

Then:

Creating a New Table

Then:

Migration Best Practices

1. Always Review Generated SQL

Don’t blindly apply migrations:
Check for:
  • Destructive operations (DROP, ALTER)
  • Missing defaults for NOT NULL columns
  • Incorrect data types

2. Test Migrations Locally First

Only deploy to production after verifying locally.

3. Use Transactions for Complex Migrations

For multi-step migrations, wrap in a transaction:
If any step fails, entire migration rolls back.

4. Never Edit Applied Migrations

Once a migration is applied:
  • Don’t edit the SQL file
  • Don’t rename the file
  • Create a new migration to fix issues
Why? Migration history must be immutable for consistency across environments.

5. Handle Breaking Changes Carefully

For destructive changes:
  1. Add new column (nullable)
  2. Migrate data from old → new
  3. Make required (add NOT NULL constraint)
  4. Drop old column (in separate migration)
This allows rollback at each step.

Troubleshooting

”Migration already applied”

Migration file exists but hasn’t been applied:

“Column already exists”

Schema out of sync with database:

“SSL connection required”

PostgreSQL SSL configuration issue:

“Cannot read properties of undefined”

Missing DATABASE_URL environment variable:

Production Deployment

For production deployments:
  1. Commit migrations to Git
  2. Deploy code with new schema file
  3. Run migrations on production database:
  4. Restart application to use new schema
Rollback strategy:
  • Keep previous deployment available
  • Test rollback migrations in staging first
  • Consider blue-green deployments for zero downtime

Next Steps