ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Convex 数据迁移组件完整指南:基于 @convex-dev/migrations 的分批可恢复迁移实战

Convex 数据迁移组件完整指南:基于 @convex-dev/migrations 的分批可恢复迁移实战 Convex 数据迁移组件完整指南基于 convex-dev/migrations 的分批可恢复迁移实战【免费下载链接】convex-backendThe open-source reactive database for app developers项目地址: https://gitcode.com/gh_mirrors/co/convex-backend导读本指南完整讲解 Convex 官方convex-dev/migrations组件一个面向 Convex 数据库的分批、可暂停、可恢复的数据迁移工具用于在生产环境中安全地回填历史数据、变更字段类型、拆分或合并表结构。读完本文你将掌握从安装、定义迁移、命令行触发、干跑验证到批量大小调优、索引子集迁移与并行化处理的完整实战能力并理解它与 Convex 加宽—迁移—收窄widen-migrate-narrow零停机迁移工作流的配合方式。本文内容以仓库内 migrations-component.md 组件参考文档为主体并辅以同目录下 migration-patterns.md 与 SKILL.md 中的迁移工作流背景展开。一、为什么需要迁移组件在线迁移与 Schema 校验约束在深入组件用法之前先理解它存在的根本原因。Convex 不会允许你部署一个与存量数据不匹配的 schema——这是塑造所有迁移流程的核心约束不能为已有文档添加必填字段如果存量文档没有该字段不能改变字段类型如果存量文档还是旧类型不能从 schema 中删除字段如果存量文档仍然携带它。因此Convex 的迁移遵循一个可预测的三段式模式加宽 schemawiden→ 迁移数据migrate→ 收窄 schemanarrow。而迁移数据这一步正是convex-dev/migrations组件的用武之地。另一个关键背景是在线迁移online migrationConvex 迁移在应用继续对外服务的同时异步分批更新数据。在迁移窗口期内你的代码必须同时兼容旧、新两种数据格式。组件正是为这种场景设计它自动处理分批batching、基于游标的分页cursor-based pagination、状态跟踪、失败续跑resume、干跑dry run与进度监控避免在大表上使用.collect()一次性拉取全部文档导致的事务限额或超时问题。使用前提说明convex-dev/migrations是以 npm 包形式发布的 Convex 组件本文所有用法均以仓库内参考文档描述为准。二、安装与项目初始化在 Convex 项目根目录安装组件包npm install convex-dev/migrations安装完成后需要做两处配置1. 在convex.config.ts中注册组件// convex/convex.config.ts import { defineApp } from convex/server; import migrations from convex-dev/migrations/convex.config.js; const app defineApp(); app.use(migrations); export default app;2. 在convex/migrations.ts中实例化迁移工具并导出 runner// convex/migrations.ts import { Migrations } from convex-dev/migrations; import { components } from ./_generated/api.js; import { DataModel } from ./_generated/dataModel.js; export const migrations new MigrationsDataModel(components.migrations); export const run migrations.runner();其中DataModel类型参数是可选的但它能为迁移定义提供完整的类型安全——编写migrateOne时能获得文档类型的自动推导与编译期检查建议在生产项目中始终传入。三、定义迁移migrateOne 与两种书写形式组件的核心抽象是migrations.define()。其中migrateOne函数负责处理单个文档而分批与分页由组件自动完成——你不必关心游标、批次边界和状态持久化// convex/migrations.ts export const addDefaultRole migrations.define({ table: users, migrateOne: async (ctx, user) { if (user.role undefined) { await ctx.db.patch(user._id, { role: user }); } }, });这里ctx是迁移上下文提供与常规 Convex 函数一致的ctx.db操作能力patch/insert/delete/query等user是当前批次中待处理的一条文档。简写形式返回值自动应用为 patch如果迁移逻辑只是把某字段改为某值可以直接在migrateOne中返回一个对象组件会自动将其作为ctx.db.patch应用无需手动调用export const clearDeprecatedField migrations.define({ table: users, migrateOne: () ({ legacyField: undefined }), });这个简写非常适合清理废弃字段这类单向、确定性的数据变换代码更短且不易出错。四、运行迁移命令行与编程式两种触发方式4.1 从命令行运行定义迁移后需要先导出一个一次性 runnerone-off runner再通过npx convex run触发。参考文档给出了两种命令行方式# 方式一为单个迁移定义一次性 runner 后运行 # 在 convex/migrations.ts 中追加 # export const runIt migrations.runner(internal.migrations.addDefaultRole); npx convex run migrations:runIt # 方式二使用通用 runner通过参数指定要执行的迁移 npx convex run migrations:run {fn: migrations:addDefaultRole}方式二更灵活migrations:run是通用入口fn参数以字符串形式指定目标迁移适合临时在 CLI 上切换要执行的迁移。4.2 从其他 Convex 函数编程式触发迁移也可以被其他 Convex 函数调用例如在管理接口、HTTP action 或定时逻辑中按需触发await migrations.runOne(ctx, internal.migrations.addDefaultRole);ctx为调用方函数的上下文第二个参数是迁移的内部引用internal.migrations.xxx。五、按顺序运行多个迁移将多个迁移以数组形式传给 runner即可按声明顺序依次执行export const runAll migrations.runner([ internal.migrations.addDefaultRole, internal.migrations.clearDeprecatedField, internal.migrations.normalizeEmails, ]);npx convex run migrations:runAll这里需要强调失败语义如果其中一个迁移失败执行会停止且不会自动继续到下一个。你可以再次调用同一命令来重试——组件会从上次中断的位置继续已完成的迁移会自动跳过。这正是可恢复迁移的核心价值大表迁移即使中途失败也无需从头再来。六、干跑Dry Run提交变更前的安全验证在真正修改生产数据之前务必先用干跑模式验证迁移逻辑。干跑会执行一个批次然后整体回滚让你看到将要做什么而不改变任何数据npx convex run migrations:runIt {dryRun: true}参考文档明确建议将干跑作为标准流程的一部分。它能在迁移真正触及真实文档之前捕获逻辑缺陷比如字段名拼写错误、条件判断写反、对 undefined 字段的不安全访问等是成本最低的保险措施。七、查看迁移状态与取消运行中的迁移7.1 查看状态使用组件提供的内置状态查询函数并配合--watch持续观察迁移进度npx convex run --component migrations lib:getStatus --watch注意这里通过--component migrations指定在组件实例上下文中运行lib:getStatus--watch会持续刷新输出适合在长迁移期间监控批次进度。7.2 取消迁移迁移过程中随时可以取消。命令行方式需要传入迁移名称npx convex run --component migrations lib:cancel {name: migrations:addDefaultRole}编程式方式同样支持await migrations.cancel(ctx, internal.migrations.addDefaultRole);八、部署时自动执行迁移迁移执行可以串联在部署命令之后形成部署即迁移的流水线npx convex deploy --cmd npm run build npx convex run migrations:runAll --prod这行命令的语义拆解先构建并部署--cmd指定构建命令部署成功后立即在生产环境--prod运行全部迁移。配合组件失败续跑、完成自动跳过的特性即使某次部署后的迁移失败重新执行也能安全地从断点继续而不会重复处理已迁移的文档。九、配置选项详解9.1 自定义批次大小batchSize默认情况下组件会按一个合理的批次大小处理文档。但当单文档体积很大或表上有较重写流量时默认批次可能触达事务限额transaction limits或引发乐观并发OCC冲突。此时应调小批次export const migrateHeavyTable migrations.define({ table: largeDocuments, batchSize: 10, migrateOne: async (ctx, doc) { // migration logic }, });batchSize的单位是每个批次处理的文档数10意味着每批次只处理 10 个文档显著降低单事务的体积与冲突概率代价是迁移总耗时变长。9.2 使用索引迁移子集customRange默认迁移扫描整张表。如果只需要处理满足特定条件的文档可以用customRange基于索引做定向筛选大幅减少扫描量export const fixEmptyNames migrations.define({ table: users, customRange: (query) query.withIndex(by_name, (q) q.eq(name, )), migrateOne: () ({ name: unknown }), });customRange接收一个查询构建函数返回值直接用于驱动分页游标。这里只处理name字段为空字符串的文档migrateOne的简写形式把它们统一补为unknown。值得注意的是customRange返回的查询同样可以是任意合法查询包括filter但基于索引withIndex的写法在扫描效率上更优。9.3 批次内并行处理parallelize默认情况下每个批次内的文档是串行处理的。如果你的迁移逻辑不依赖处理顺序例如各文档之间相互独立、不互相查询可以开启并行以提升吞吐export const clearField migrations.define({ table: myTable, parallelize: true, migrateOne: () ({ optionalField: undefined }), });需要自行判断的前提并行处理意味着同一批次内的migrateOne并发执行因此迁移逻辑绝不能依赖文档间顺序例如先处理 A 再处理 B或在同一批次内查询另一个待处理文档的最新状态这类写法都不适合开启parallelize。十、与其他迁移模式的配合零停机工作流将组件放入完整的迁移流程才能发挥其全部价值。参考文档建议任何非平凡迁移都应使用该组件并结合widen-migrate-narrow多部署工作流Deploy 1 —— 加宽 schema更新 schema允许旧、新两种格式并存例如新增一个 optional 字段更新读取代码兼容两种格式更新写入代码让新文档写入新格式部署。两次部署之间 —— 迁移数据5. 用组件运行迁移回填存量文档 6. 验证所有文档均已迁移可用lib:getStatus --watch或编写校验查询。Deploy 2 —— 收窄 schema7. 更新 schema 只保留新格式 8. 移除兼容旧格式的代码 9. 部署。在迁移窗口期内配合**双写dual write或双读dual read**策略保证新旧格式数据的一致性与可回滚性。这里有一个重要的顺序纪律必须在运行迁移之前就让新代码开始写新格式否则迁移窗口期内新建的文档会被漏掉导致迁移完成后仍有未迁移数据。同时应避免两个常见误区在迁移数据之前就把字段设为必填——Convex 会因为存量文档缺少该字段而拒绝部署用 cron 任务代替组件做分批——组件的分批基于内部递归调度自动完成而 cron 需要额外部署清理且没有断点续跑能力。十一、常见陷阱与迁移检查清单常见陷阱速览迁移前就收窄 schema先在 Deploy 1 加宽再迁移最后收窄对大表使用.collect()会命中事务限额或超时务必用组件做分批分页.collect()只适用于确认很小的表迁移窗口期新写入仍是旧格式先改写入代码再跑迁移避免漏网之鱼跳过干跑dryRun: true能在触碰真实文档前捕获逻辑错误过早物理删除字段优先用v.optional弃用并加注释确认无代码引用后再删除用 cron 做分批组件内部已处理递归调度cron 需要额外清理部署。迁移检查清单识别破坏性变更规划多部署工作流更新 schema 兼容新旧格式更新读取代码兼容两种格式更新写入代码新文档写新格式部署加宽后的 schema 与代码用convex-dev/migrations组件定义迁移以dryRun: true测试运行迁移并监控状态验证所有文档已迁移收窄 schema 为仅新格式清理兼容旧格式的代码部署最终 schema 与代码确认稳定后移除迁移代码。十二、小结convex-dev/migrations组件把分批、分页、状态跟踪、断点续跑、干跑、进度监控这些易错的基础设施全部内建让你只需聚焦于migrateOne中如何变换单条文档这一业务逻辑。配合batchSize、customRange、parallelize三个配置项它可以覆盖从海量表全量回填到定向索引子集处理的绝大多数迁移场景。将其嵌入 widen-migrate-narrow 的零停机部署流程再以干跑验证、状态监控收尾即可在生产环境中安全、可控地完成任何 Convex 数据迁移。如需查阅完整的工作流与更多模式添加必填字段、删除字段、类型变更、嵌套数据拆分表、孤儿文档清理、双写/双读策略、小表快捷方式、迁移验证可继续阅读仓库内的 SKILL.md 与 migration-patterns.md。【免费下载链接】convex-backendThe open-source reactive database for app developers项目地址: https://gitcode.com/gh_mirrors/co/convex-backend创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表