d1-drizzle-schema by jezweb/claude-skills
npx skills add https://github.com/jezweb/claude-skills --skill d1-drizzle-schema为 Cloudflare D1 生成正确的 Drizzle ORM 模式。D1 基于 SQLite,但存在重要差异,如果使用标准的 SQLite 模式会导致微妙的错误。此技能生成的模式能够正确适配 D1 的约束。
| 特性 | 标准 SQLite | D1 |
|---|---|---|
| 外键 | 默认关闭 | 始终开启(无法禁用) |
| 布尔类型 | 无 | 无 —— 使用 integer({ mode: 'boolean' }) |
| 日期时间类型 | 无 | 无 —— 使用 integer({ mode: 'timestamp' }) |
| 最大绑定参数 | ~999 | 100(影响批量插入) |
| JSON 支持 | 扩展功能 | 始终可用(json_extract, ->, ->>) |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 并发性 | 多写入器 | 单线程(一次只能执行一个查询) |
收集需求:需要哪些表、存在什么关系、哪些需要索引。如果基于现有描述工作,则直接推断模式。
使用适配 D1 的列模式创建模式文件:
import { sqliteTable, text, integer, real, index, uniqueIndex } from 'drizzle-orm/sqlite-core'
export const users = sqliteTable('users', {
// UUID 主键(D1 推荐使用)
id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()),
// 文本字段
name: text('name').notNull(),
email: text('email').notNull(),
// 枚举(存储为 TEXT,在模式层面验证)
role: text('role', { enum: ['admin', 'editor', 'viewer'] }).notNull().default('viewer'),
// 布尔值(D1 没有 BOOL 类型 —— 存储为 INTEGER 0/1)
emailVerified: integer('email_verified', { mode: 'boolean' }).notNull().default(false),
// 时间戳(D1 没有 DATETIME 类型 —— 存储为 Unix 秒数)
createdAt: integer('created_at', { mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
// 类型化 JSON(存储为 TEXT,Drizzle 自动序列化)
preferences: text('preferences', { mode: 'json' }).$type<UserPreferences>(),
// 外键(在 D1 中始终强制执行)
organisationId: text('organisation_id').references(() => organisations.id, { onDelete: 'cascade' }),
}, (table) => ({
emailIdx: uniqueIndex('users_email_idx').on(table.email),
orgIdx: index('users_org_idx').on(table.organisationId),
}))
完整的类型参考请查看 references/column-patterns.md。
Drizzle 关系是查询构建器的辅助工具(与外键约束分开):
import { relations } from 'drizzle-orm'
export const usersRelations = relations(users, ({ one, many }) => ({
organisation: one(organisations, {
fields: [users.organisationId],
references: [organisations.id],
}),
posts: many(posts),
}))
export type User = typeof users.$inferSelect
export type NewUser = typeof users.$inferInsert
将 assets/drizzle-config-template.ts 复制到 drizzle.config.ts 并更新模式路径。
添加到 package.json:
{
"db:generate": "drizzle-kit generate",
"db:migrate:local": "wrangler d1 migrations apply DB --local",
"db:migrate:remote": "wrangler d1 migrations apply DB --remote"
}
在测试之前,务必在本地和远程都运行。
为后续会话记录模式:
D1 将绑定参数限制为 100 个。计算批次大小:
const BATCH_SIZE = Math.floor(100 / COLUMNS_PER_ROW)
for (let i = 0; i < rows.length; i += BATCH_SIZE) {
await db.insert(table).values(rows.slice(i, i + BATCH_SIZE))
}
import { drizzle } from 'drizzle-orm/d1'
import * as schema from './schema'
// 在 Worker fetch 处理程序中:
const db = drizzle(env.DB, { schema })
// 查询模式
const all = await db.select().from(schema.users).all() // Array<User>
const one = await db.select().from(schema.users).where(eq(schema.users.id, id)).get() // User | undefined
const count = await db.select({ count: sql`count(*)` }).from(schema.users).get()
| 何时使用 | 阅读 |
|---|---|
| D1 与 SQLite 对比、JSON 查询、限制 | references/d1-specifics.md |
| Drizzle + D1 的列类型模式 | references/column-patterns.md |
| 文件 | 用途 |
|---|---|
| assets/drizzle-config-template.ts | 适用于 D1 的初始 drizzle.config.ts |
| assets/schema-template.ts | 包含所有常见 D1 模式的示例模式 |
每周安装量
502
代码仓库
GitHub 星标数
650
首次出现
2026年2月18日
安全审计
安装于
opencode460
codex453
github-copilot453
gemini-cli451
cursor441
kimi-cli439
Generate correct Drizzle ORM schemas for Cloudflare D1. D1 is SQLite-based but has important differences that cause subtle bugs if you use standard SQLite patterns. This skill produces schemas that work correctly with D1's constraints.
| Feature | Standard SQLite | D1 |
|---|---|---|
| Foreign keys | OFF by default | Always ON (cannot disable) |
| Boolean type | No | No — use integer({ mode: 'boolean' }) |
| Datetime type | No | No — use integer({ mode: 'timestamp' }) |
| Max bound params | ~999 | 100 (affects bulk inserts) |
| JSON support | Extension | Always available (json_extract, ->, ->>) |
| Concurrency | Multi-writer | Single-threaded (one query at a time) |
Gather requirements: what tables, what relationships, what needs indexing. If working from an existing description, infer the schema directly.
Create schema files using D1-correct column patterns:
import { sqliteTable, text, integer, real, index, uniqueIndex } from 'drizzle-orm/sqlite-core'
export const users = sqliteTable('users', {
// UUID primary key (preferred for D1)
id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()),
// Text fields
name: text('name').notNull(),
email: text('email').notNull(),
// Enum (stored as TEXT, validated at schema level)
role: text('role', { enum: ['admin', 'editor', 'viewer'] }).notNull().default('viewer'),
// Boolean (D1 has no BOOL — stored as INTEGER 0/1)
emailVerified: integer('email_verified', { mode: 'boolean' }).notNull().default(false),
// Timestamp (D1 has no DATETIME — stored as unix seconds)
createdAt: integer('created_at', { mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
// Typed JSON (stored as TEXT, Drizzle auto-serialises)
preferences: text('preferences', { mode: 'json' }).$type<UserPreferences>(),
// Foreign key (always enforced in D1)
organisationId: text('organisation_id').references(() => organisations.id, { onDelete: 'cascade' }),
}, (table) => ({
emailIdx: uniqueIndex('users_email_idx').on(table.email),
orgIdx: index('users_org_idx').on(table.organisationId),
}))
See references/column-patterns.md for the full type reference.
Drizzle relations are query builder helpers (separate from FK constraints):
import { relations } from 'drizzle-orm'
export const usersRelations = relations(users, ({ one, many }) => ({
organisation: one(organisations, {
fields: [users.organisationId],
references: [organisations.id],
}),
posts: many(posts),
}))
export type User = typeof users.$inferSelect
export type NewUser = typeof users.$inferInsert
Copy assets/drizzle-config-template.ts to drizzle.config.ts and update the schema path.
Add to package.json:
{
"db:generate": "drizzle-kit generate",
"db:migrate:local": "wrangler d1 migrations apply DB --local",
"db:migrate:remote": "wrangler d1 migrations apply DB --remote"
}
Always run on BOTH local AND remote before testing.
Document the schema for future sessions:
D1 limits bound parameters to 100. Calculate batch size:
const BATCH_SIZE = Math.floor(100 / COLUMNS_PER_ROW)
for (let i = 0; i < rows.length; i += BATCH_SIZE) {
await db.insert(table).values(rows.slice(i, i + BATCH_SIZE))
}
import { drizzle } from 'drizzle-orm/d1'
import * as schema from './schema'
// In Worker fetch handler:
const db = drizzle(env.DB, { schema })
// Query patterns
const all = await db.select().from(schema.users).all() // Array<User>
const one = await db.select().from(schema.users).where(eq(schema.users.id, id)).get() // User | undefined
const count = await db.select({ count: sql`count(*)` }).from(schema.users).get()
| When | Read |
|---|---|
| D1 vs SQLite, JSON queries, limits | references/d1-specifics.md |
| Column type patterns for Drizzle + D1 | references/column-patterns.md |
| File | Purpose |
|---|---|
| assets/drizzle-config-template.ts | Starter drizzle.config.ts for D1 |
| assets/schema-template.ts | Example schema with all common D1 patterns |
Weekly Installs
502
Repository
GitHub Stars
650
First Seen
Feb 18, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode460
codex453
github-copilot453
gemini-cli451
cursor441
kimi-cli439
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
105,000 周安装
LLM提示词缓存优化指南:降低90%成本,实现多级缓存与语义匹配
323 周安装
小红书内容转换器:一键将通用文章转为小红书爆款笔记格式 | AI写作助手
323 周安装
内容摘要AI工具:智能提取YouTube、网页、PDF和推文内容,支持测验学习和深度探索
324 周安装
Notion知识捕获工具 - 将对话笔记自动转化为结构化Notion页面 | 知识管理自动化
324 周安装
现代Angular最佳实践指南:TypeScript严格性、信号响应式、性能优化与测试
324 周安装
iOS VoIP 通话开发:CallKit + PushKit 集成原生通话 UI 指南
324 周安装