drizzle-migrations
Drizzle ORM migrations for Neon PostgreSQL. Use when creating database schemas, running migrations, or troubleshooting Drizzle issues.
When & Why to Use This Skill
This Claude skill streamlines database management by providing comprehensive support for Drizzle ORM migrations on Neon PostgreSQL. It simplifies schema definition, automates migration generation, and offers expert troubleshooting for common database synchronization issues, ensuring a robust, type-safe development workflow for modern web applications.
Use Cases
- Initial Database Setup: Configuring drizzle.config.ts and establishing serverless connections to Neon PostgreSQL with optimized settings.
- Schema Design & Evolution: Defining complex table structures with automated timestamps, relations, and TypeScript type inference using Drizzle's core patterns.
- Migration Lifecycle Management: Generating, reviewing, and applying SQL migrations across development and production environments using drizzle-kit commands.
- Troubleshooting & Debugging: Resolving common ORM-related errors such as 'relation does not exist', schema-type mismatches, and synchronization issues.
| name | drizzle-migrations |
|---|---|
| description | Drizzle ORM migrations for Neon PostgreSQL. Use when creating database schemas, running migrations, or troubleshooting Drizzle issues. |
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
- Dev:
- Update types: Types auto-update from schema
Common Issues
"relation does not exist"
- Migration not applied
- Run:
pnpm drizzle-kit push(dev) ormigrate(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