更新记录
1.0.0(2026-11-11)
首个版本。
- 十个 action:parse / validate / begin / push / finish / batches / detail / rollback / clean
- CSV 与 JSON 解析,含引号、CRLF、有无表头
- 行级校验:必填、类型、枚举、预置格式、长度、批内唯一
- 默认 dry-run,commit 与 rollback 必须显式 confirm
- 按批次记录 _id,可精确回滚且不影响其他数据
- 目标集合白名单,令牌只从环境变量读
平台兼容性
云端兼容性
| 支付宝云 | 腾讯云 | 阿里云 |
|---|---|---|
| × | √ | √ |
uniCloud 批量导入与数据校验
零第三方依赖的 uniCloud 云端一体工具:解析 CSV / JSON、按规则逐行校验、分批游标导入、默认 dry-run 不写业务数据、错误行报告、按批次回滚,附一个开箱即用的管理页。
和「云数据库快照与导出」是一对:那个负责把数据取出来,这个负责把数据安全地放回去。适合运营批量导数据、系统初始化、从旧表迁移、上线前灌测试数据。
特性
- 自带 CSV 解析:处理引号、逗号、换行、CRLF、表头,不引任何 npm 包
- 行级校验:必填、类型、枚举、格式、长度、批内唯一,输出行号 / 字段 / 原因,不存原始行
- 默认 dry-run:
begin不传mode就是试算,只统计不写业务集合;commit必须显式传confirm: true - 分批游标导入:单次最多 100 行,管理页自动循环;批次记录累计成功 / 失败 / 错误摘要
- 按批次回滚:记录本批次写入的
_id,只删自己写过的行,不碰其他数据;同样要求confirm: true - 集合白名单:
IMPORT_COLLECTIONS之外的集合一律拒绝;令牌、白名单、批次集合名只从环境变量读 - 数据不出空间:所有批次记录只写在使用者自己的服务空间
- 自带管理页:粘贴文本 → 解析预览 → 试导入 / 正式导入 → 批次详情 → 回滚
目录结构
uni_modules/aliang-cloud-import/
├── package.json 插件配置(含定价与加密清单,只列 1 个 js)
├── pages_init.json 自动注册管理页
├── readme.md / changelog.md
├── uniCloud/
│ ├── cloudfunctions/aliang-cloud-import/index.js 单文件云函数
│ └── database/
│ ├── cloud_import_batches.schema.json
│ └── cloud_import_batches.index.json 两个索引
└── pages/import/list.vue 管理页
云函数刻意做成单文件:付费普通授权版的加密清单按文件配置,多文件结构一旦漏配某个 lib,那个文件会明文留在用户项目里且不会有任何报错。
五分钟接入
第 0 步:在 uniCloud 服务空间的环境变量里配置:
IMPORT_TOKEN = 一个足够长的随机字符串
IMPORT_COLLECTIONS = demo_orders,goods,users
未配置令牌时除 ping 外所有 action 拒绝;未配置白名单时拒绝写入任何集合。这是默认安全,不是故障。
- 导入插件到 uni-app 项目。
- 上传
uniCloud/database/cloud_import_batches.schema.json。 - 右键
uniCloud/cloudfunctions/aliang-cloud-import→ 上传部署。 pages_init.json会自动提示注册「批量导入」页。- 管理页填令牌和集合名,点「检查」→「解析预览」→「试导入 dry-run」。
试用 5 分钟自检(7 天试用内照做即可判定插件是否合用)
| 步骤 | 操作 | 预期结果 |
|---|---|---|
| 1 | action: 'ping' |
configured: true,defaultMode: "dry-run" |
| 2 | 管理页粘贴两行 CSV,点「解析预览」 | 显示字段名、总行数与前 5 行预览 |
| 3 | 点「试导入 dry-run」 | 批次状态 done,业务集合行数不变 |
| 4 | 查看「导入批次」详情 | 能看到成功数、失败数、错误行摘要 |
| 5 | 确认无误后点「正式导入 commit」并确认弹窗 | 业务集合新增对应行 |
| 6 | 对该批次点「按批次回滚」 | 只删除本批次写入的行,其他数据不变 |
任一步不符,先看页面顶部错误提示和「常见问题」,再检查 IMPORT_COLLECTIONS 是否包含目标集合。
环境变量
| 变量 | 默认 | 说明 |
|---|---|---|
IMPORT_TOKEN |
空(必填) | 所有 action 的令牌,只从环境变量读 |
IMPORT_COLLECTIONS |
空(必填) | 允许写入的集合白名单,逗号分隔;* 允许全部非保留集合 |
IMPORT_BATCH_COLLECTION |
cloud_import_batches |
批次记录集合名,只从环境变量读 |
IMPORT_PAGE_SIZE |
100 | 单次 push 行数上限 |
IMPORT_MAX_ROWS |
5000 | 单次解析行数上限(ping 里可见) |
IMPORT_MAX_STRING / IMPORT_MAX_ERRORS / IMPORT_MAX_ROW_IDS |
4000 / 100 / 5000 | 截断与记录上限 |
IMPORT_RETENTION_DAYS |
7 | 批次记录保留天数 |
分页、行数、截断参数可用 data.config 覆盖;令牌、白名单、批次集合名不接受请求侧覆盖。
API 参考
云函数名 aliang-cloud-import,统一返回 { errCode: 0 | 字符串, errMsg, data },失败错误码以 aliang-cloud-import- 开头。
| action | 说明 | 主要参数 | 需要 token |
|---|---|---|---|
ping |
健康检查(不含数据) | — | 否 |
parse |
解析 CSV / JSON,返回字段与最多 500 行 | text format delimiter hasHeader |
是 |
validate |
行级校验 | rows rules |
是 |
begin |
创建批次 | collection mode confirm fields operator |
是 |
push |
分批推送行 | batchId rows |
是 |
finish |
结束批次 | batchId |
是 |
batches |
批次列表 | page pageSize |
是 |
detail |
批次详情与错误预览 | batchId |
是 |
rollback |
按批次回滚 | batchId confirm |
是 |
clean |
清理过期批次记录 | — | 是 |
parse 单次最多返回 500 行(避免撑爆云函数返回体);更大批量请按游标分段构造 rows 多次 push。
push 返回 written(实际写入行数,dry-run 恒为 0)、wouldWrite(本次试算可写行数)、skipped(写入失败行数)与 rowIdsTruncated(可回滚 ID 是否达到上限)。dry-run 不会记录可回滚的 _id。
校验规则(rules 以字段名为键):
| 键 | 说明 |
|---|---|
required |
必填 |
type |
string / number / boolean / date |
enum |
允许值数组 |
pattern |
预置格式:email / phone / date / number / idcard(不接受自定义正则,避免 ReDoS) |
maxLength |
最大长度 |
unique |
批内唯一 |
完整接入示例
const importFn = (action, extra) => uniCloud.callFunction({
name: 'aliang-cloud-import',
data: Object.assign({ action, token: TOKEN }, extra)
}).then(r => r.result)
const parsed = await importFn('parse', { text: csvText, format: 'csv' })
const checked = await importFn('validate', {
rows: parsed.data.rows,
rules: { name: { required: true }, age: { type: 'number' }, email: { pattern: 'email' } }
})
if (checked.data.failed) return { errCode: 'invalid-rows', errMsg: '存在不合法行' }
const b = await importFn('begin', { collection: 'goods', mode: 'dry-run' })
for (let i = 0; i < checked.data.rows.length; i += 100) {
await importFn('push', { batchId: b.data.batchId, rows: checked.data.rows.slice(i, i + 100) })
}
const dry = await importFn('finish', { batchId: b.data.batchId })
// 人工核对 dry.data 后,再以 mode:'commit', confirm:true 重跑一遍
commit 与 rollback 都要求显式 confirm: true,防止误写与误删。
安全与隐私
- 令牌、白名单、批次集合名只从环境变量读,
data.config改不了。 - 字段名做了清理(去
$前缀、点号替换、长度限制),不参与数据库命令拼接。 - 错误报告只存行号、字段名、原因,不存原始行内容;批次记录不保存导入数据正文。
- 批次集合
permission全为false,前端无法直连。 - 回滚按
_id精确删除本批次写入的行;row_ids有上限,超限后回滚可能不完整,返回值rowIdsTruncated会提示。 commit前请先用dry-run核对,并用快照插件留一份底稿;回滚是辅助手段,不替代备份。- 管理页只应放在后台,不要把令牌写进前端代码。
限制
parse单次最多 500 行;push单次默认 100 行,大批量靠游标循环。- 写入时若行自带
_id且已存在,写入会失败并计入错误行;插件不做覆盖更新。 pattern只支持 5 种预置格式,不支持自定义正则(安全考虑)。- 第一版不提供字段映射 UI、去重合并、类型转换后的自动修复。
- dry-run 是试算:会走完整统计与错误记录,但不写业务集合。
常见问题
Q:报 token-required / unauthorized。 没配 IMPORT_TOKEN 或管理页填的不一致,用 ping 确认。
Q:报 collection-not-allowed。 IMPORT_COLLECTIONS 没有该集合,注意大小写与逗号分隔。
Q:报 confirm-required。 commit 或 rollback 没传 confirm: true,这是防误操作设计。
Q:报 collection-missing。 批次 Schema 没上传;业务集合不存在时也需要先建。
Q:正式导入后数据没变。 检查是否用了 dry-run(默认),以及 push 返回的 written 是否为 0。
Q:回滚只删了一部分。 row_ids 达到 IMPORT_MAX_ROW_IDS 上限被截断,看 push 返回的 rowIdsTruncated。
版本要求与授权
HBuilderX 4.71+,uniCloud 阿里云 / 腾讯云;JavaScript 普通云函数(CommonJS),零扩展库。付费普通授权版按服务空间 spaceId 绑定,提供 7 天试用。
授权按 DCloud 插件市场的标准条款,可用于自己的任意商业项目,项目数量不限;禁止把插件本身(含换皮版本)作为插件 / 源码 / 模板再次分发或转售。
运行时行为要点
- 回滚可能不完整:
row_ids有上限(IMPORT_MAX_ROW_IDS,默认 5000)。单批次写入超过这个数时,超出的行没有记录_id,回滚只能删掉记录下来的那部分。这时rollback返回partial: true与unrecovered(约多少行没删到),批次状态记rolled-back-partial,不会谎报「已回滚」。大批量导入建议分批次做,每批不超过 5000 行。 - 回滚可以分多次调用:一次调用最多处理
IMPORT_ROLLBACK_BATCH_IDS(默认 1000)个_id,返回nextOffset时带上它继续调即可。 parse按字符预算截断:除了 500 行上限,还有IMPORT_MAX_RESPONSE_CHARS(默认 30 万字符)兜底,避免长字段把云函数返回体撑爆。rowsTruncated: true时请分段取。clean只清已结束的批次(done/rolled-back/rolled-back-partial)。还在running的过期批次不会被删,否则row_ids丢了就永远无法回滚。返回值里的notCleaned是还剩多少条没清掉。- 校验产出的
_row不会入库:validate会带行号方便定位,push时自动过滤,业务集合里不会多出这个字段。

收藏人数:
购买源码授权版(
导入插件并试用
赞赏(0)
下载 0
赞赏 1
下载 35291
赞赏 159
赞赏
京公网安备:11010802035340号