Loading...
Loading...
Type-safe ORM for Cloudflare D1 databases using Drizzle. Use when: building D1 database schemas, writing type-safe SQL queries, managing migrations with Drizzle Kit, defining table relations, implementing prepared statements, using D1 batch API, or encountering D1_ERROR, transaction errors, foreign key constraint failures, or schema inference issues. Keywords: drizzle orm, drizzle d1, type-safe sql, drizzle schema, drizzle migrations, drizzle kit, orm cloudflare, d1 orm, drizzle typescript, drizzle relations, drizzle transactions, drizzle query builder, schema definition, prepared statements, drizzle batch, migration management, relational queries, drizzle joins, D1_ERROR, BEGIN TRANSACTION d1, foreign key constraint, migration failed, schema not found, d1 binding error, schema design, database indexes, soft deletes, uuid primary keys, enum constraints, performance optimization, naming conventions, schema testing
npx skill4agent add secondsky/claude-skills drizzle-orm-d1bun add drizzle-orm drizzle-kitdrizzle.config.tsimport { defineConfig } from 'drizzle-kit';
export default defineConfig({
schema: './src/db/schema.ts',
out: './migrations',
dialect: 'sqlite',
driver: 'd1-http',
dbCredentials: {
accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
databaseId: process.env.CLOUDFLARE_DATABASE_ID!,
token: process.env.CLOUDFLARE_D1_TOKEN!,
},
});src/db/schema.tsimport { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
import { relations } from 'drizzle-orm';
export const users = sqliteTable('users', {
id: integer('id').primaryKey({ autoIncrement: true }),
email: text('email').notNull().unique(),
name: text('name').notNull(),
createdAt: integer('created_at', { mode: 'timestamp' }).$defaultFn(() => new Date()),
});
export const posts = sqliteTable('posts', {
id: integer('id').primaryKey({ autoIncrement: true }),
title: text('title').notNull(),
content: text('content').notNull(),
authorId: integer('author_id')
.notNull()
.references(() => users.id, { onDelete: 'cascade' }),
});
export const usersRelations = relations(users, ({ many }) => ({
posts: many(posts),
}));bunx drizzle-kit generate # Generate SQL
bunx wrangler d1 migrations apply my-database --local # Apply local
bunx wrangler d1 migrations apply my-database --remote # Apply prodimport { drizzle } from 'drizzle-orm/d1';
import { users } from './db/schema';
import { eq } from 'drizzle-orm';
export default {
async fetch(request: Request, env: { DB: D1Database }): Promise<Response> {
const db = drizzle(env.DB);
const allUsers = await db.select().from(users).all();
return Response.json(allUsers);
},
};| Rule | Why |
|---|---|
Use | Never write SQL manually |
| Test migrations locally first | |
Use | Returns first row or undefined |
Use | D1 doesn't support SQL BEGIN/COMMIT |
Use | D1 has no native date type |
Use | Not |
| Rule | Why |
|---|---|
Use SQL | D1 requires batch API (Error #1) |
Mix | Use Wrangler only |
Use | Use |
| Commit credentials in drizzle.config.ts | Use env vars |
Use | Use |
| # | Error | Solution |
|---|---|---|
| 1 | | Use |
| 2 | | Define cascading: |
| 3 | | Ensure binding in |
| 4 | | Use |
| 5 | | Use |
references/error-catalog.md| Pattern | Use Case | Template |
|---|---|---|
| CRUD Operations | Basic database operations | |
| Relations & Joins | Nested queries, manual joins | |
| Batch Operations | Transactions (D1 batch API) | |
| Schema Design | Naming, indexes, soft deletes | |
| File | Purpose | Template |
|---|---|---|
| Drizzle Kit configuration | |
| D1 binding setup | |
| npm scripts for migrations | |
{
"db:generate": "drizzle-kit generate",
"db:migrate:local": "wrangler d1 migrations apply my-database --local",
"db:migrate:remote": "wrangler d1 migrations apply my-database --remote"
}| Step | Command | Notes |
|---|---|---|
| 1. Edit schema | Edit | Make changes |
| 2. Generate | | Creates SQL migration |
| 3. Test local | | Verify locally |
| 4. Deploy code | | Push to Cloudflare |
| 5. Apply prod | | Apply migration |
references/migration-workflow.mdimport { InferSelectModel, InferInsertModel } from 'drizzle-orm';
import { users } from './db/schema';
export type User = InferSelectModel<typeof users>;
export type NewUser = InferInsertModel<typeof users>;| Reference | Load When... |
|---|---|
| Debugging D1 errors, transaction failures, binding issues |
| Designing schemas, naming conventions, indexes, soft deletes |
| Setting up or troubleshooting migrations |
| Complex queries, operators, joins syntax |
| Configuring wrangler.jsonc for D1 |
| Quick error lookup |
basic-schema.tsbasic-queries.tstransactions.tsrelations-queries.tsprepared-statements.tsdrizzle.config.tspackage.jsonerror-catalog.mdschema-patterns.mdmigration-workflow.mdquery-builder-api.mdwrangler-setup.mdcommon-errors.mdlinks-to-official-docs.md{
"dependencies": {
"drizzle-orm": "^0.44.7"
},
"devDependencies": {
"drizzle-kit": "^0.31.7"
}
}