mcpField
D
d1-migration

d1-migration

github.com/jezweb数据与数据库1.1k1.2k 次安装3 周前更新
代码仓库

关于 d1-migration

面向使用 Drizzle ORM 与 Cloudflare D1 的开发者,提供数据库迁移工作流指南。它涵盖 SQL 检查、本地与远程应用、迁移验证及故障处理,并说明批量插入和命名约定。

主要功能

  1. 01生成并检查迁移 SQL
  2. 02应用本地和远程迁移
  3. 03验证数据库结构与迁移记录
  4. 04诊断并修复卡住的迁移
  5. 05分批执行大量插入

适用场景

  1. 01检查生成的迁移是否会重建表
  2. 02同步 D1 本地与远程数据库结构
  3. 03排查迁移重复列或未记录问题
  4. 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 数据库时,请按以下顺序操作:

  1. 先部署 Worker — npm run build && npx wrangler deploy
  2. 创建 D1 数据库 — npx wrangler d1 create project-name-db
  3. 将 database_id 复制到 wrangler.jsonc 的 d1_databases 绑定
  4. 重新部署 — npx wrangler deploy
  5. 运行迁移 — 同时应用到本地和远程

评论

支持 Markdown