关于 d1-migration
面向使用 Drizzle ORM 与 Cloudflare D1 的开发者,提供数据库迁移工作流指南。它涵盖 SQL 检查、本地与远程应用、迁移验证及故障处理,并说明批量插入和命名约定。
主要功能
- 01生成并检查迁移 SQL
- 02应用本地和远程迁移
- 03验证数据库结构与迁移记录
- 04诊断并修复卡住的迁移
- 05分批执行大量插入
适用场景
- 01检查生成的迁移是否会重建表
- 02同步 D1 本地与远程数据库结构
- 03排查迁移重复列或未记录问题
- 04避免批量插入触及参数限制
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ jezweb/ claude-skills --skill d1-migration安装后在 Claude Code 中输入/d1-migration确认已加载。
详细介绍
D1 迁移工作流
使用 Drizzle ORM 进行 Cloudflare D1 数据库迁移的引导式工作流。
标准迁移流程
1. 生成迁移
pnpm db:generate
这会在 drizzle/(或你配置的迁移目录)中创建一个新的 .sql 文件。
2. 检查 SQL(至关重要)
应用前务必检查生成的 SQL。 对于简单的架构更改,Drizzle 有时会生成具有破坏性的迁移。
警示信号:重建表
如果看到以下模式,迁移很可能会失败:
CREATE TABLE `my_table_new` (...);
INSERT INTO `my_table_new` SELECT ..., `new_column`, ... FROM `my_table`;
-- ^^^ This column doesn't exist in old table!
DROP TABLE `my_table`;
ALTER TABLE `my_table_new` RENAME TO `my_table`;
原因:在 Drizzle 架构中更改列的 default 值会触发完整的表重建。INSERT SELECT 会从旧表中引用新列。
修复方法:如果你只是添加新列(不更改现有列的类型或约束),请简化为:
ALTER TABLE `my_table` ADD COLUMN `new_column` TEXT DEFAULT 'value';
应用前直接编辑 .sql 文件。
3. 应用到本地
pnpm db:migrate:local
# or: npx wrangler d1 migrations apply DB_NAME --local
4. 应用到远程
pnpm db:migrate:remote
# or: npx wrangler d1 migrations apply DB_NAME --remote
测试前务必同时应用到本地和远程。 仅应用到本地的迁移会导致“本地运行正常,生产环境却出问题”这类令人困惑的情况。
5. 验证
# Check local
npx wrangler d1 execute DB_NAME --local --command "PRAGMA table_info(my_table)"
# Check remote
npx wrangler d1 execute DB_NAME --remote --command "PRAGMA table_info(my_table)"
修复卡住的迁移
当迁移仅部分应用(例如,已添加列,但迁移未记录)时,wrangler 会重试并因列重复而失败。
症状:pnpm db:migrate 在一个看似应该已完成的迁移上报错。PRAGMA table_info 显示该列已存在。
诊断
# 1. Verify the column/table exists
npx wrangler d1 execute DB_NAME --remote \
--command "PRAGMA table_info(my_table)"
# 2. Check what migrations are recorded
npx wrangler d1 execute DB_NAME --remote \
--command "SELECT * FROM d1_migrations ORDER BY id"
修复
# 3. Manually record the stuck migration
npx wrangler d1 execute DB_NAME --remote \
--command "INSERT INTO d1_migrations (name, applied_at) VALUES ('0013_my_migration.sql', datetime('now'))"
# 4. Run remaining migrations normally
pnpm db:migrate
预防
CREATE TABLE IF NOT EXISTS—— 可安全地重复运行ALTER TABLE ADD COLUMN—— SQLite 没有IF NOT EXISTS变体;请先检查列是否存在,或在应用代码中使用 try/catch- 应用前务必检查生成的 SQL(见上文第 2 步)
批量插入分批处理
D1 的参数数量限制会导致大型多行 INSERT 静默失败。请分批处理:
const BATCH_SIZE = 10;
for (let i = 0; i < allRows.length; i += BATCH_SIZE) {
const batch = allRows.slice(i, i + BATCH_SIZE);
await db.insert(myTable).values(batch);
}
原因:当行数 x 列数超过约 100-150 个参数时,D1 会失败。
列命名
| 上下文 | 约定 | 示例 |
|---|---|---|
| Drizzle 架构 | 驼峰命名法 | caseNumber: text('case_number') |
| 原始 SQL 查询 | 下划线命名法 | UPDATE cases SET case_number = ? |
| API 响应 | 与 SQL 别名一致 | SELECT case_number FROM cases |
新项目设置
为新项目创建 D1 数据库时,请按以下顺序操作:
- 先部署 Worker —
npm run build && npx wrangler deploy - 创建 D1 数据库 —
npx wrangler d1 create project-name-db - 将 database_id 复制到
wrangler.jsonc的d1_databases绑定 - 重新部署 —
npx wrangler deploy - 运行迁移 — 同时应用到本地和远程
评论
支持 Markdown