# @convex-dev/migrations 中文文档

规范地址：https://npmcn.com/package/%40convex-dev/migrations/

版本：0\.3\.7
npm 元数据更新时间：2026-10-10T00:07:11.258Z
中文译文更新时间：2026-11-10T17:37:41.061Z
软件包许可：Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40convex-dev/migrations
原文对照：https://npmcn.com/package/%40convex-dev/migrations/?lang=original
项目主页：https://github.com/get-convex/migrations#readme
源码仓库：https://github.com/get-convex/migrations

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：235 kB，57 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：0 个
- peer 依赖：convex ^1\.42\.0，convex-helpers ^0\.1\.115
- 首次发布：2024-09-20T23:24:31.005Z
- 最新版本发布：2026-10-10T00:07:10.875Z
- 近 30 天下载量：2303978（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：31（近 12 个月 11 个）

## 中文简介

Convex 的迁移组件 。 定义、运行和跟踪您的数据库迁移 。 从 CLI 或 Convex 服务器函数运行 .

## 安装

```sh
npm install @convex-dev/migrations
```

也可以使用：`pnpm add @convex-dev/migrations`、`yarn add @convex-dev/migrations`、`bun add @convex-dev/migrations`

## README

# 国家移徙部分

[![npm version](https://badge.fury.io/js/@convex-dev%2Fmigrations.svg)](https://badge.fury.io/js/@convex-dev%2Fmigrations)

定义和运行迁移, 如此设定用户的默认值 :

```ts
export const setDefaultValue = migrations.define({
  table: "users",
  migrateOne: async (ctx, user) => {
    if (user.optionalField === undefined) {
      await ctx.db.patch(user._id, { optionalField: "default" });
    }
  },
});
```

然后可以从CLI或程序上直接运行. 见 [下级](https://npmcn.com/package/%40convex-dev/migrations/#readme-running-migrations-one-at-a-time)。 。 。 .

```sh
npx convex run migrations:setDefaultValue
```

迁移允许您定义表格中所有文档上的函数 (或指定的子集). 它们分批同步运行(在线迁移).

组件跟踪迁移状态, 避免运行两次, 抓取 (如果在路上发生错误或故障) 通过 Convex 查询实时迁移状态.

见 [迁移入门员额](https://stack.convex.dev/intro-to-migrations) 为在线对离线迁移的概念概述。 如果你的迁徙是 小事一桩,你走得很快,还检查一下 [仪表板中的轻量级迁移](https://stack.convex.dev/lightweight-zero-downtime-migrations)。 。 。 .

移徙的典型步骤:

1.  修改您的方案以允许新旧值。 通常这是添加一个 新建可选字段或将一个字段标为可选字段,以便删除。 作为 部分内容,更新您的代码处理两个版本.
2.  定义将数据转换到新方案.
3.  推动迁移和计划变化.
4.  运行迁移到完成 .
5.  修改您的策略和代码以承担新值 。 推动这一变化 只有在所有数据都符合新方案时才会成功。 这是默认 convex的行为,除非您禁用计划验证 .

见 [此堆栈帖](https://stack.convex.dev/migrating-data-with-mutations) 用于普通使用案例.

## 预先要求: Convex

你需要一个现有的 Convex 项目来使用组件。 Convex 是一个主机 后端平台,包括数据库、无服务器功能和多一个吨 可以学习 [这里](https://docs.convex.dev/get-started)。 。 。 .

运行 `npm create convex` 或遵循其中任何一条 [快速启动](https://docs.convex.dev/home) 来设置一个.

## 安装

安装组件包 :

```ts
npm install @convex-dev/migrations
```

创建一个 `convex.config.ts` 应用程序中的文件 `convex/` 文件夹并安装 通过调用 `use`数字 :

```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;
```

## 初始化

下面的例子假设该代码是在 `convex/migrations.ts`。这不是一个 页:1 如果您想要使用不同的文件, 请务必更改 下面的例子 `internal.migrations.*` 到您的新文件名, 如 `internal.myFolder.myMigrationsFile.*` 或 CLI 参数类 `migrations:*` 改为 `myFolder/myMigrationsFile:*`。 。 。 .

```ts
import { Migrations } from "@convex-dev/migrations";
import { components } from "./_generated/api.js";
import schema from "./_generated/schema.js";

export const migrations = new Migrations(components.migrations, { schema });
```

这个 `schema` 为移徙定义和支持提供类型安全 在自定义索引上加页 [`customRange`](https://npmcn.com/package/%40convex-dev/migrations/#readme-migrating-a-subset-of-a-table-using-an-index)。 。 。 . 与往常一样,迁移中的数据库操作将得到遵守 根据您运行时的策略定义. **说明**: 如果您使用的话 [自定义函数](https://stack.convex.dev/custom-functions) 要覆盖 `internalMutation`,参见 [下级](https://npmcn.com/package/%40convex-dev/migrations/#readme-override-the-internalmutation-to-apply-custom-db-behavior)。 。 。 .

## 定义迁移

内部 `migrateOne` 函数,您可以写入代码来修改单个文档 在指定的表格中。 改变是可选的,你也可以阅读 写入此函数的其他表格.

```ts
export const setDefaultValue = migrations.define({
  table: "myTable",
  migrateOne: async (ctx, doc) => {
    if (doc.optionalField === undefined) {
      await ctx.db.patch(doc._id, { optionalField: "default" });
    }
  },
});
```

### 短期语法

由于最常见的迁移包括补丁每个文档,如果返回 对象,将自动作为补丁应用.

```ts
export const clearField = migrations.define({
  table: "myTable",
  migrateOne: () => ({ optionalField: undefined }),
});
// is equivalent to `await ctx.db.patch(doc._id, { optionalField: undefined })`
```

### 使用索引移动表格的子集

如果您想要迁移一系列文档, 您可以避免处理 表格全文,以指定 `customRange`。您可以使用任何已有索引 或内置 `by_creation_time` 指数.

```ts
import { Migrations } from "@convex-dev/migrations";
import { components } from "./_generated/api.js";
import schema from "./_generated/schema.js";

export const migrations = new Migrations(components.migrations, { schema });

export const validateRequiredField = migrations.define({
  table: "myTable",
  customRange: (query) =>
    query.withIndex("by_requiredField", (q) => q.eq("requiredField", "")),
  migrateOne: async (_ctx, doc) => {
    console.log("Needs fixup: " + doc._id);
    // Shorthand for patching
    return { requiredField: "<unknown>" };
  },
});
```

注意: 要使用自定义 Range, 您必须向移民提供您的计划 .

## 一次进行一次迁移

### 使用 Dashboard 或 CLI

管理移民的最简单方式是直接称呼:

```sh
npx convex run migrations:setDefaultValue
```

过 `--prod` 用于生产.

在仪表板上运行:

![Dashboard screenshot](https://npmcn.com/package/%40convex-dev/migrations/dashboard_screenshot.png)

您也可以定义接受迁移的通用跑道:

```ts
export const run = migrations.runner();
```

那就用那个 [函数名称](https://docs.convex.dev/functions/query-functions#query-names)数字 :

```sh
npx convex run migrations:run '{fn: "migrations:setDefaultValue"}'
```

见 [下级](https://npmcn.com/package/%40convex-dev/migrations/#readme-shorthand-running-syntax) 以通过的方式 `setDefaultValue`。 。 。 .

### 程序

也可以运行来自其他 Convex 变异或动作的迁移 :

```ts
await migrations.runOne(ctx, internal.example.setDefaultValue);
```

### 行为

-   如果它已经在运行,它会拒绝再开始一个重复的工人.
-   如果它以前在一些批次上失败了,它将继续从该批次开始 除非您手动指定 `cursor` 或者说 `reset`。 。 。 .
-   如果你提供明确 `cursor` (单位:千美元)`null` 表示从头开始, 从那里开始.
-   如果你通过了 `reset: true`,它会重新开始迁移 该组的所有迁移(包括任何迁移) `next` 移民问题).
-   如果你通过了 `true` 页:1 `dryRun` 然后它会运行一批 然后扔,所以 你可以看到它会做什么。 见 [下级](https://npmcn.com/package/%40convex-dev/migrations/#readme-test-a-migration-with-dryrun) 这对验证它有用 你所期望的.

## 连续进行迁移

可以按顺序进行一系列迁移. 如果有迁移的话, 这样做是有用的 取决于先前的,或者如果您保留所有迁移的运行列表 下个部署就应该开始.

### 使用 Dashboard 或 CLI

您可以通过迁移列表到 `runner` 让它运行一系列 移徙,而不只是一次:

```ts
export const runAll = migrations.runner([
  internal.migrations.setDefaultValue,
  internal.migrations.validateRequiredField,
  internal.migrations.convertUnionField,
]);
```

然后就运行:

```sh
npx convex run migrations:runAll # migrations:runAll is equivalent to convex/migrations.ts:runAll on the CLI
```

直接拨打移民电话时,或与 `runner` 函数,您可以通过 一个"next"的参数在第一次迁移后运行一系列迁移:

```sh
npx convex run migrations:setDefaultValue '{next:["migrations:clearField"]}'
# OR
npx convex run migrations:run '{fn: "migrations:setDefaultValue", next:["migrations:clearField"]}'
```

### 程序

```ts
await migrations.runSerially(ctx, [
  internal.migrations.setDefaultValue,
  internal.migrations.validateRequiredField,
  internal.migrations.convertUnionField,
]);
```

### 行为

-   如果在试图迁移时已经在进行中,那就行不通.
-   如果迁移已经完成,它将跳过它.
-   如果移徙有部分进展,移徙将恢复原状.
-   如果一次迁移失败或被取消,它将不再继续,如果您有的话 移民之间的一些依赖关系。 再次调用系列重试.

注意:如果开始多次串行迁移,行为是:

-   如果它们在功能上不重叠,它们就会快乐地平行运行.
-   如果他们有一个共同的功能,一个在另一个尝试之前完成 它,第二会只是跳过它.
-   如果它们有一个共同的功能,一个正在进行,第二个将 不再继续移动.

## 业务

### 用干流测试迁移

在运行可能不可逆转地更改数据的迁移之前,您可以验证一个 批次通过 `dryRun` 对任意 `runner` 或者说 `runOne` 命令 :

```sh
npx convex run migrations:setDefaultValue '{dryRun: true}'
```

### 重新开始迁移

过 `reset: true` 迫使移民从头开始.

```sh
npx convex run migrations:setDefaultValue '{reset: true}'
```

如果您指定 `next` 或运行定义的迁移序列,这将重设 光标指向组中的所有迁移.

```sh
npx convex run migrations:runAll '{reset: true}'
```

您也可以从任何有效的光标中通过。 您可以找到有效的光标 答复 `getStatus`。这可以允许重试迁移 从一个已知的好点, 当你在代码上.

注意:如果您正在从 CLI 的特定光标开始迁移,或者 仪表板,不要通过 `dryRun: false` 明确,不要定义它.

### 停止迁移

您可以停止 CLI 或仪表板的迁移, 调用组件 API 直接 :

```sh
npx convex run --component migrations lib:cancel '{name: "migrations:myMigration"}'
```

或者通过 `migrations.cancel` 程序上.

```ts
await migrations.cancel(ctx, internal.migrations.myMigration);
```

### 获取移民状况

要了解移民的动态状况,你可以通过 CLI: 爱丽丝

```sh
npx convex run --component migrations lib:getStatus --watch
```

这个 `--watch` 随时更新状态 或在方案方面:

```ts
const status: MigrationStatus[] = await migrations.getStatus(ctx, {
  limit: 10,
});
// or
const status: MigrationStatus[] = await migrations.getStatus(ctx, {
  migrations: [
    internal.migrations.setDefaultValue,
    internal.migrations.validateRequiredField,
    internal.migrations.convertUnionField,
  ],
});
```

该类型被注释为避免循环类型依赖, 例如, 如果您 正在返回一个查询的结果,该查询在同一个文件中被定义 引用的迁移.

### 作为生产部署的一部分进行迁移

作为构建和部署命令的一部分,你可以将相应的命令链条链条 `npx convex run` 命令,例如:

```sh
npx convex deploy --cmd 'npm run build' && npx convex run convex/migrations.ts:runAll --prod
```

## 配置选项

### 覆盖内部Mutation以应用自定义 DB 行为

您可以自定义哪个 `internalMutation` b. 减少移徙 应用.

如果你用的话,这可能很重要 [自定义函数](https://stack.convex.dev/custom-functions) 要拦截 数据库写入以应用验证或 [更改时触发操作](https://stack.convex.dev/triggers)。 。 。 .

假设您定义自己的 `internalMutation` 内 `convex/functions.ts`数字 :

```ts
import { internalMutation } from "./functions";
import { Migrations } from "@convex-dev/migrations";
import { components } from "./_generated/api";

export const migrations = new Migrations(components.migrations, {
  internalMutation,
});
```

见 [本条](https://stack.convex.dev/migrating-data-with-mutations) 页:1 关于使用和先进模式的更多信息.

### 自定义批量大小

该组件将获取您的数据, 分批为100, 并调用您的功能 每批文档。 如果您想要更改批量大小, 您可以指定 这个 如果您的文档是大的, 这会有所帮助, 以避免运行在 [交易限制](https://docs.convex.dev/production/state/limits#transactions), (中文(简体) ), 或文档经常更新且您正在看到OCC 冲突 在迁徙时.

```ts
export const clearField = migrations.define({
  table: "myTable",
  batchSize: 10,
  migrateOne: () => ({ optionalField: undefined }),
});
```

您也可以在单个引用时覆盖此批量大小 :

```ts
await migrations.runOne(ctx, internal.migrations.clearField, {
  batchSize: 1,
});
```

### 平行批次

每个批次都是按序处理的,但是在一个批次内,你可以拥有每个批次 `migrateOne` 如果通过, 呼叫并行运行 `parallelize: true`如果你这样做, 保证你的回话不会认为每个电话都是孤立的 例如,如果 每次通话读取后都会更新相同的计数器,然后在 同样的批量可以读取相同的反相值,然后从一个上下车. 结果, 迁移在默认情况下进行.

```ts
export const clearField = migrations.define({
  table: "myTable",
  parallelize: true,
  migrateOne: () => ({ optionalField: undefined }),
});
```

### 短手运行语法 :

对不想打字的人来说 `migrations:myNewMigration` 每一次 他们从CLI或仪表盘上运行一个迁移,特别是如果你定义你的 其他地方的移民情况 `ops/db/migrations:myNewMigration`,您可以配置 前缀 :

```ts
export const migrations = new Migrations(components.migrations, {
  internalMigration,
  migrationsLocationPrefix: "migrations:",
});
```

然后打电话给:

```sh
npx convex run migrations:run '{fn: "myNewMutation", next: ["myNextMutation"]}'
```

或用代码 :

```ts
await migrations.getStatus(ctx, { migrations: ["myNewMutation"] });
await migrations.cancel(ctx, "myNewMutation");
```

## 同步进行迁移

如果您想要从测试或动作同步运行迁移, 您可以使用 `runToCompletion`。请注意,如果动作崩溃或被取消,则不会 在背景中继续迁徙.

从动作 :

```ts
import { components, internal } from "./_generated/api";
import { internalAction } from "./_generated/server";
import { runToCompletion } from "@convex-dev/migrations";

export const myAction = internalAction({
  args: {},
  handler: async (ctx) => {
    //...
    const toRun = internal.example.setDefaultValue;
    await runToCompletion(ctx, components.migrations, toRun);
  },
});
```

在测试中:

```ts
import { test } from "vitest";
import { convexTest } from "convex-test";
import component from "@convex-dev/migrations/test";
import { runToCompletion } from "@convex-dev/migrations";
import { components, internal } from "./_generated/api";
import schema from "./schema";

test("test setDefaultValue migration", async () => {
  const t = convexTest(schema);
  // Register the component in the test instance
  component.register(t);

  await t.run(async (ctx) => {
    // Add sample data to migrate
    await ctx.db.insert("myTable", { optionalField: undefined });

    // Run the migration to completion
    const migrationToTest = internal.example.setDefaultValue;
    await runToCompletion(ctx, components.migrations, migrationToTest);

    // Assert that the migration was successful by checking the data
    const docs = await ctx.db.query("myTable").collect();
    expect(docs.every((doc) => doc.optionalField !== undefined)).toBe(true);
  });
});
```

## 常见问题

### @convex-dev/migrations 是什么？

Convex 的迁移组件 。 定义、运行和跟踪您的数据库迁移 。 从 CLI 或 Convex 服务器函数运行 \.

### 如何安装 @convex-dev/migrations？

在项目目录运行 npm install @convex-dev/migrations，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：convex（^1\.42\.0）、convex-helpers（^0\.1\.115）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @convex-dev/migrations 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @convex-dev/migrations 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @convex-dev/migrations 可以商用吗？

@convex-dev/migrations 使用 Apache-2\.0 许可。宽松许可：允许商业使用、修改和再分发，并附带明确的专利授权；分发时需保留许可与 NOTICE 文件，修改过的文件要注明改动。以上为概括，不构成法律意见，请以许可原文为准。

### @convex-dev/migrations 的下载量有多少？

根据 npm 官方下载统计，@convex-dev/migrations 在 2026/10/11 – 2026/11/09 这 30 天内被下载 2,303,978 次，日均约 76,799 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @convex-dev/migrations 还在维护吗？

最新版本 0\.3\.7 发布于 2026/10/10（1 个月前）；至今共发布 31 个版本，其中过去 12 个月发布了 11 个；首次发布于 2024/09/21。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

