Files
nocobase_migration_tools/docs/collection-schema-import-export.md

406 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# NocoBase Collection 结构导入导出脚本使用说明
本文说明如何使用项目中的两个脚本,在 NocoBase 环境之间导出、检查和导入主数据源的 Collection 结构。
- 导出脚本:`script/export-collection-schema.sh`
- 导入脚本:`script/import-collection-schema.sh`
## 1. 适用范围
脚本迁移以下内容:
- 主数据源 `main` 中的 Collection 定义;
- Collection 的普通字段和关系字段;
- Collection 分类及分类成员关系;
- Collection 和字段中可移植的配置属性。
脚本不迁移以下内容:
- Collection 中的业务数据记录;
- 非主数据源中的 Collection
- 页面、区块和菜单配置;
- 角色、权限和用户授权;
- 工作流、自动化和通知配置;
- 插件配置及环境变量。
导入脚本只接受由导出脚本生成的、`profile``portable``dataSource``main` 的导出包。
## 2. 运行前准备
请从项目根目录执行命令,并确认本机已安装:
- NocoBase CLI`nb`
- JSON 工具:`jq`
检查命令:
```sh
command -v nb
command -v jq
```
同时需要满足以下条件:
1. 源环境和目标环境已经配置为可用的 NocoBase CLI 环境;
2. 当前 CLI 身份可以读取源环境的数据模型;
3. 正式导入时,当前 CLI 身份可以在目标环境创建或更新 Collection、字段和 Collection 分类;
4. 目标环境应安装导出结构所依赖的字段接口或插件;
5. 关系字段引用的外部 Collection 必须已经存在于目标环境。
可分别查看两个脚本的内置帮助:
```sh
./script/export-collection-schema.sh --help
./script/import-collection-schema.sh --help
```
## 3. 推荐操作流程
建议始终按以下顺序执行:
1. 从源环境导出 Collection 结构;
2. 检查导出目录中的 `manifest.json` 和 Collection JSON 文件;
3. 对目标环境执行导入预演,不加 `--apply`
4. 核对预演输出中的环境、Collection 数量、字段数量、分类和外部关系目标;
5. 确认无误后使用 `--apply``--confirm-env` 正式导入;
6. 检查脚本最终输出的 `verified: true`
## 4. 导出 Collection 结构
### 4.1 命令格式
```sh
./script/export-collection-schema.sh \
--env <源环境名称> \
--output-dir <导出目录> \
[--category <Collection 分类名称>] \
[--no-overwrite]
```
### 4.2 参数说明
| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `--env` | 是 | NocoBase CLI 中已配置的源环境名称。 |
| `--output-dir` | 是 | 导出包保存目录。目录不存在时会自动创建。 |
| `--category` | 否 | 只导出指定 Collection 分类。必须与 NocoBase 中的分类名称完全一致;不指定时导出全部分类及未分类 Collection。 |
| `--no-overwrite` | 否 | 如果输出目录已经存在则终止,不覆盖原目录。 |
| `-h``--help` | 否 | 显示帮助信息。 |
数据源无需指定。导出脚本固定读取主数据源 `main`,也不接受 `--data-source` 参数。
### 4.3 导出全部 Collection
```sh
./script/export-collection-schema.sh \
--env master-data-local \
--output-dir ./exports/all-collection-schema
```
未指定 `--category` 时:
- 脚本读取主数据源中的全部 Collection
- 已加入分类的 Collection 按分类写入导出目录;
- 未加入任何分类的 Collection 写入伪分类目录 `未分类`
- 同一个 Collection 属于多个分类时,会在多个分类目录中生成相同的结构文件,以保留全部分类关系。
### 4.4 按分类导出
```sh
./script/export-collection-schema.sh \
--env master-data-local \
--category 参考数据 \
--output-dir ./exports/reference-schema
```
导出未加入分类的 Collection
```sh
./script/export-collection-schema.sh \
--env master-data-local \
--category 未分类 \
--output-dir ./exports/unclassified-schema
```
如果分类名称不存在,脚本会退出并列出当前可用的分类名称。
> **分类关系警告:** 使用 `--category` 时,导出包只记录所选分类,不会记录这些 Collection 在其他分类中的成员关系。正式导入会以导出包为准协调本次涉及 Collection 的分类关系,因此可能将它们从目标环境的其他分类中移除。如果需要完整保留全部分类关系,应不指定 `--category`,导出全部 Collection 和分类关系。
### 4.5 输出目录覆盖规则
默认情况下,如果输出目录已经存在,脚本会:
1. 先在同一父目录生成完整的临时导出目录;
2. 将旧输出目录临时改名;
3. 用新目录替换旧目录;
4. 替换成功后删除旧目录;
5. 替换失败时尝试恢复旧目录。
如需禁止覆盖,请添加 `--no-overwrite`
```sh
./script/export-collection-schema.sh \
--env master-data-local \
--output-dir ./exports/reference-schema \
--no-overwrite
```
### 4.6 导出包结构
典型目录结构如下:
```text
exports/reference-schema/
├── manifest.json
└── main/
└── 参考数据/
├── ref_code_sets.json
├── ref_code_set_versions.json
└── ref_code_items.json
```
`manifest.json` 记录:
- 源环境名称;
- 固定数据源 `main`
- 导出分类或 `all`
- 导出时间;
- 覆盖策略;
- 发现和导出的 Collection 数量;
- 导出文件数量;
- 每个文件对应的分类、Collection 和相对路径。
每个 Collection JSON 文件保存经过标准化的可移植结构。导出时会排除部分由 NocoBase 自动生成或与当前实例绑定的内容,例如:
- `id`、创建时间、更新时间、创建人和更新人等系统字段;
- 文件 Collection 和树形 Collection 的部分内置字段;
- 实例内部使用的 `key``collectionName``parentKey` 等标识。
导出完成后,脚本会在标准输出中返回一份不包含文件明细的 JSON 摘要。
## 5. 导入 Collection 结构
### 5.1 命令格式
```sh
./script/import-collection-schema.sh \
--env <目标环境名称> \
--input-dir <导出包目录> \
[--apply --confirm-env <同一目标环境名称>]
```
### 5.2 参数说明
| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `--env` | 是 | NocoBase CLI 中已配置的目标环境名称。 |
| `--input-dir` | 是 | 导出脚本生成的目录,其中必须包含 `manifest.json`。 |
| `--apply` | 否 | 正式写入目标环境。不指定时只生成预演计划,不进行任何写入。 |
| `--confirm-env` | 正式导入时必填 | 必须与 `--env` 完全一致,用于降低误操作到错误环境的风险。 |
| `-h``--help` | 否 | 显示帮助信息。 |
### 5.3 第一步:导入预演
先执行不带 `--apply` 的命令:
```sh
./script/import-collection-schema.sh \
--env mdm-uat \
--input-dir ./exports/reference-schema
```
预演模式只读取和校验本地导出包,不写入目标 NocoBase 环境。输出示例:
```json
{
"mode": "plan",
"writes": false,
"targetEnvironment": "mdm-uat",
"sourceEnvironment": "master-data-local",
"profile": "portable",
"dataSource": "main",
"collections": 3,
"scalarFields": 12,
"relationFields": 4,
"categories": [
"参考数据"
],
"categoryRelations": 3,
"externalRelationTargets": []
}
```
正式导入前至少核对:
- `targetEnvironment` 是否为预期目标环境;
- `sourceEnvironment` 是否为预期源环境;
- `collections``scalarFields``relationFields` 数量是否合理;
- `categories` 是否符合预期;
- `unclassifiedCollections` 中是否存在不应取消分类的 Collection
- `externalRelationTargets` 引用的 Collection 是否已在目标环境存在。
注意:预演不会连接目标环境检查外部关系目标是否实际存在,该检查在正式导入、首次写入之前执行。
### 5.4 第二步:正式导入
确认预演结果后执行:
```sh
./script/import-collection-schema.sh \
--env mdm-uat \
--input-dir ./exports/reference-schema \
--apply \
--confirm-env mdm-uat
```
`--confirm-env` 的值必须与 `--env` 完全相同。例如,`--env mdm-uat` 必须配合 `--confirm-env mdm-uat`
正式导入前,脚本会先完成以下检查:
- 导出包结构和全部 JSON 文件有效;
- manifest 声明的数据源为 `main`
- Collection 名称、字段名称和文件路径合法且无重复冲突;
- 目标环境可访问且当前身份已认证;
- 目标环境不存在重名的 Collection 分类;
- 导出包以外的关系目标已存在于目标环境。
检查通过后,脚本按四个阶段执行:
1. 创建或更新 Collection,并应用非关系字段;
2. 应用 `m2o``o2m``m2m``o2o` 关系字段;
3. 创建缺失分类并协调 Collection 分类成员关系;
4. 从服务器回读 Collection、字段和分类关系并校验。
成功时输出类似:
```json
{
"mode": "applied",
"writes": true,
"verified": true,
"targetEnvironment": "mdm-uat",
"sourceEnvironment": "master-data-local",
"profile": "portable",
"dataSource": "main",
"collections": 3,
"scalarFields": 12,
"relationFields": 4,
"categoryMembership": "verified"
}
```
只有出现 `verified: true`,才表示脚本已完成服务器回读校验。
## 6. 导入合并与分类处理规则
### 6.1 Collection 和字段
- 已存在的 Collection 会被更新;不存在的 Collection 会被创建;
- 导入包中的普通字段和关系字段会被创建或更新;
- 导入使用 `replaceFields: false`,不会删除目标环境中额外存在的字段;
- 脚本不会删除目标环境中额外存在的 Collection
- 如果目标结构无法包含导出包声明的结构,回读校验会失败并输出差异。
### 6.2 Collection 分类
- 导出包中存在、目标环境中不存在的分类会被创建;
- 对本次导入涉及的 Collection,分类成员关系会调整为导出包声明的状态;
- 目标分类中不属于本次导入范围的其他 Collection 会被保留;
- `未分类` 是导出使用的伪分类,不会在目标环境创建同名分类;
- 被标记为 `未分类` 的 Collection 会从目标环境现有分类中移除。
因此,导入前应重点检查预演结果中的 `categories``unclassifiedCollections`。对于按单个分类生成的导出包,还应确认是否允许移除本次 Collection 在目标环境中的其他分类关系。
## 7. 完整迁移示例
以下示例将本地环境中的“参考数据”分类迁移到 UAT 环境。
### 7.1 从源环境导出
```sh
./script/export-collection-schema.sh \
--env master-data-local \
--category 参考数据 \
--output-dir ./exports/reference-schema \
--no-overwrite
```
### 7.2 查看导出清单
```sh
jq . ./exports/reference-schema/manifest.json
```
列出导出的 Collection
```sh
jq -r '.files[].collection' ./exports/reference-schema/manifest.json | sort -u
```
### 7.3 在目标环境执行预演
```sh
./script/import-collection-schema.sh \
--env mdm-uat \
--input-dir ./exports/reference-schema
```
### 7.4 正式导入并回读验证
```sh
./script/import-collection-schema.sh \
--env mdm-uat \
--input-dir ./exports/reference-schema \
--apply \
--confirm-env mdm-uat
```
## 8. 常见错误及处理
### `nb CLI is required`
当前终端找不到 `nb`。请安装或配置 NocoBase CLI,并确认 `command -v nb` 能返回可执行文件路径。
### `jq is required`
当前终端找不到 `jq`。请先安装 `jq`,并确认 `command -v jq` 能返回可执行文件路径。
### `Unknown category`
`--category` 指定的名称与源环境中的 Collection 分类不完全一致。请根据错误信息列出的分类名称重新执行。
### `Output directory already exists`
使用了 `--no-overwrite`,但输出目录已经存在。请更换目录、移走旧目录,或确认允许替换后去掉 `--no-overwrite`
### `Invalid manifest.json: portable main-data-source export required`
输入目录不是当前导出脚本生成的主数据源可移植包,或 `manifest.json` 已被修改。请重新导出,不要手工修改 manifest 中的数据源、文件路径和数量字段。
### `External relation target is unavailable`
某个关系字段引用了未包含在导出包中的 Collection,而该 Collection 在目标环境不存在。请先在目标环境创建或迁移这个依赖 Collection,再重新导入。
### `--apply requires --confirm-env to exactly equal --env`
正式导入缺少环境确认,或者两个环境名称不一致。请检查目标环境后重新传入完全相同的值。
### `Import read-back verification failed`
写入完成后的实际结构未包含导出包声明的结构。脚本会输出 Collection、字段或分类关系的预期值与实际值。请根据差异检查:
- 目标环境的 NocoBase 版本和插件是否支持对应字段接口;
- 关系字段的目标 Collection 和反向字段配置是否有效;
- 当前身份是否拥有完整的数据模型修改权限;
- 目标环境是否存在同名但不兼容的字段或 Collection 配置。
该错误可能发生在部分写入已经完成之后。修正问题后,应重新执行预演,再执行正式导入并确认最终返回 `verified: true`
## 9. 使用注意事项
- 正式导入前,建议先对目标环境创建可恢复的备份;
- 不要跳过预演,也不要仅凭进程退出码判断结构完全一致,应检查最终 JSON 中的 `verified`
- 导出包中的 JSON 文件适合纳入版本管理,以便审阅结构变化;
- 不建议手工修改导出包;如确需修改,应同时保证 `manifest.json`、文件路径、Collection 名称及重复分类文件保持一致;
- Collection 结构迁移完成后,业务数据、ACL、页面和工作流需要使用各自独立的迁移与验证流程。