Drizzle ORM Migrations
Setup
drizzle.config.ts
import { defineConfig } from 'drizzle-kit';
export default defineConfig({
schema: './src/db/schema.ts',
out: './drizzle',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL!,
},
});
Connection (Neon Serverless)
// src/db/index.ts
import { drizzle } from 'drizzle-orm/neon-http';
import { neon } from '@neondatabase/serverless';
import * as schema from './schema';
const sql = neon(process.env.DATABASE_URL!);
export const db = drizzle(sql, { schema });
Schema Patterns
Standard Table with Timestamps
import { pgTable, text, timestamp, uuid, boolean } from 'drizzle-orm/pg-core';
const timestamps = {
createdAt: timestamp('created_at').defaultNow().notNull(),
updatedAt: timestamp('updated_at').defaultNow().notNull(),
};
export const projects = pgTable('projects', {
id: uuid('id').primaryKey().defaultRandom(),
name: text('name').notNull(),
userId: uuid('user_id').notNull().references(() => users.id),
isActive: boolean('is_active').default(true).notNull(),
...timestamps,
});
Type Inference
export type Project = typeof projects.$inferSelect;
export type NewProject = typeof projects.$inferInsert;
Relations
import { relations } from 'drizzle-orm';
export const usersRelations = relations(users, ({ many }) => ({
projects: many(projects),
}));
export const projectsRelations = relations(projects, ({ one }) => ({
owner: one(users, {
fields: [projects.userId],
references: [users.id],
}),
}));
Migration Commands
# Generate migration from schema changes
pnpm drizzle-kit generate
# Push schema directly (dev only, no migration file)
pnpm drizzle-kit push
# Apply migrations (production)
pnpm drizzle-kit migrate
# Open Drizzle Studio GUI
pnpm drizzle-kit studio
Workflow
- Modify schema.ts
- Generate migration:
pnpm drizzle-kit generate
- Review SQL: Check
drizzle/ folder
- Apply:
- Dev:
pnpm drizzle-kit push
- Prod:
pnpm drizzle-kit migrate
- Update types: Types auto-update from schema
Common Issues
"relation does not exist"
- Migration not applied
- Run:
pnpm drizzle-kit push (dev) or migrate (prod)
"column X does not exist"
- Schema out of sync
- Generate new migration and apply
Type errors after schema change
- Restart TypeScript server
- Run:
pnpm typecheck