ARTICLE DETAIL

资讯详情

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

NocoDB 无代码模式迁移实战:exportSchema / importSchema 脚本实现 Base 结构克隆

NocoDB 无代码模式迁移实战:exportSchema / importSchema 脚本实现 Base 结构克隆 NocoDB 无代码模式迁移实战exportSchema / importSchema 脚本实现 Base 结构克隆【免费下载链接】nocodb A Free Self-hostable Airtable Alternative项目地址: https://gitcode.com/GitHub_Trending/no/nocodb本文介绍 NocoDB 仓库中packages/nocodb/tests/export-import/目录下的一套导出-导入脚本它通过 NocoDB REST APInocodb-sdk把一个 Base 的完整结构表、字段、关系型字段、视图及其排序/过滤/表单配置导出为 JSON 文件再导入为一个新 Base并可选地把源 Base 的数据一并复制过去。读完后你能掌握如何配置config.json、如何执行导出与导入、导出 JSON 的结构是什么、导入脚本按什么依赖顺序重建字段与视图以及数据回迁阶段分页读取与关系字段修复的具体做法。一、目录组成与适用场景这套脚本位于 packages/nocodb/tests/export-import/包含 4 个文件文件作用ReadMe.md使用说明config.json 配置项、导出/导入执行命令config.json运行时配置文件源/目标 Base 名、服务端地址、认证令牌exportSchema.js导出脚本读取源 Base 结构写出srcProject.jsonimportSchema.js导入脚本按 JSON 重建结构并在源 Base 存在时复制数据适用场景在两个 NocoDB 实例或同一实例内之间迁移 Base 的模式schema而不依赖界面手工重建字段关系和视图配置。需要注意其设计前提结构迁移走 JSON 文件数据迁移不走 JSON——导入阶段如果源 Base 仍存在于当前实例中脚本会直接通过 API 从源 Base 分页拉取数据而不是把行数据写进导出文件。二、config.json 配置详解baseURL与xc-auth是导入和导出两个脚本共用的配置完整参数如下以仓库中实际提交的 config.json 为准{ srcProject: sample, dstProject: sample-copy, excludeDt: true, baseURL: http://localhost:8080, xc-auth: Copy Auth Token }srcProject源 Base 的名称。导出时脚本会用它定位 Base 并生成srcProject.json名称中的空格会被替换为下划线导入时它表示要导入的 JSON 文件名不含 .json 后缀。dstProject导入时新 Base 的名称仅导入阶段使用。excludeDt仅 exportSchema.js 使用的可选项。为true时导出 JSON 中的字段会省略dt底层数据类型字段只保留uidtUI 类型等字段让导入端根据uidt自行决定底层类型为false或省略时dt也会一并导出。脚本源码中有一个明确的fixme注释当字段默认值cdf被配置为0/null/false时removeEmpty过滤逻辑会把它们一并剔除这是已知边界。baseURLNocoDB 服务端地址如http://localhost:8080。xc-authAPI 认证令牌个人访问令牌占位值Copy Auth Token需替换为真实值。两个脚本都会把上述配置组装为 SDK 的连接参数其中xc-auth被放进请求头// exportSchema.js 中的配置装载importSchema.js 同理 let ncConfig { baseName: inputConfig.srcProject, baseURL: inputConfig.baseURL, headers: { xc-auth: ${inputConfig[xc-auth]} } };运行前提NocoDB 服务端已启动默认监听 8080、目标导入的 Base 名可重复创建见下文导入流程脚本会先删后建且nocodb-sdk、jsonfile依赖可用——nocodb-sdk在 packages/nocodb/package.json 中声明为workspace:^指向本仓库的 packages/nocodb-sdk。三、执行导出node exportSchema.jscd packages/nocodb/tests/export-import node exportSchema.js执行后脚本在当前目录生成srcProject.json如sample.json。导出流程可拆为四步全部基于 exportSchema.js 的源码3.1 定位 Base 并建立 ID-名称映射exportSchema()先调用api.base.list()按标题找到源 Base然后执行generateMapTbl(p.id)。这一步遍历所有表把表 ID、字段 ID、视图 ID、视图字段 ID 四类 ID 分别映射到名称存入全局ncMap。之所以要建这张映射表是因为 NocoDB 内部大量引用的是随机生成的 ID如fk_relation_column_id而跨实例迁移时 ID 必然变化必须改用名称做锚点这正是导出/导入脚本以 title 为键的根源。3.2 收集每个视图的列、排序、过滤详情storeViewDetails(tableId)对每张表的每个视图按类型分别取数Formtype1api.dbView.formRead(v.id)取表单列含label、required、description等Gallerytype2api.dbView.galleryRead(v.id)额外保留封面图字段fk_cover_image_col_idGridtype3api.dbView.gridColumnsList(v.id)保留列宽width所有非 Form 视图还会读取api.dbTableSort.list(v.id)排序fk_column_id、direction、order与api.dbTableFilter.read(v.id)过滤fk_column_id、logical_op、comparison_op、value、order。视图自身的property对 Form 视图会导出heading、subheading、success_msg、redirect_after_secs、email、submit_another_form、show_blank_form等表单属性见 addViewDetails。3.3 字段级数据的裁剪addColumnSpecificData每个字段默认只保留id、title、column_name、uidt、pk、pv、rqd、dtxp、system、ai以及非 excludeDt 时的dt再经removeEmpty剔除空值null/0/false。对四种重字段附加colOptions字段类型UITypes附带的 colOptionsFormulaformula、formula_rawLinkToAnotherRecordfk_model_id、fk_related_model_id、fk_child_column_id、fk_parent_column_id、typehm/bt/mmLookupfk_model_id、fk_relation_column_id、fk_lookup_column_idRollupfk_model_id、fk_relation_column_id、fk_rollup_column_id、rollup_function导出时还会做三类过滤把系统自动生成的镜像/占位列剔除排除标题含_nc_m2m_的多对多中间列、排除含前缀hm 列的列、排除system 1且类型为 LinkToAnotherRecord 的系统链接列见 exportSchema.js 主循环。3.4 写出 JSON最终结构是一个数组每个元素形如[ { id: 表ID, title: 表名, table_name: 物理表名, columns: [ { id: ..., title: 字段名, uidt: 2, pk: 1, colOptions: { ... } } ], views: [ { id: ..., title: 视图名, type: 3, columns: [...], sort: [...], filter: [...] } ] } ]写入时把 Base 名中的空格替换成下划线${ncConfig.baseName.replace(/ /g, _)}.json以 2 空格缩进保存。四、执行导入node importSchema.jscd packages/nocodb/tests/export-import node importSchema.js导入阶段的srcProject指向要导入的 JSON 文件名不含.jsondstProject是新 Base 名称。importSchema.js 的importSchema()主函数定义了严格的执行顺序base.list - 删除同名 dstProject若存在- base.create(dstProject) - createBaseTables - createLinks - createLookup - createRollup - createFormula - configureGrid - configureGallery - configureForm - 若源 Base 仍存在restoreBaseData - restoreLinks4.1 建表先建普通字段关系型字段延后createBaseTables()对 JSON 中每张表把字段分成两拨普通字段随api.dbTable.create()一次性建出LinkToAnotherRecord、Lookup、Rollup、Formula 四类字段被收集到全局数组link/lookup/rollup/formula中留待后续阶段。原因很直接链接字段依赖双方表存在Lookup/Rollup 依赖链接字段Formula 依赖被引用的普通字段——必须按依赖拓扑分阶段创建。建表时同时维护一张核心映射表ncTables它用v1 表 ID、v2 表 ID、表标题三个键指向同一个新表对象后续所有旧 ID → 新 ID的换算都靠它配合字段 title 匹配完成。4.2 链接字段对称列识别与 mm 去重createLinks()处理hmone-to-many 宿主侧与mmmany-to-many两类链接bt侧由 NocoDB 服务端在创建 hm/mm 时自动生成对称列mm 去重isLinkCreated()以(child, parent)列 ID 对判重避免一张多对多关系被两侧表各创建一次对称列改名创建链接后会重新api.dbTable.read()目标表按fk_parent_column_id/fk_child_column_id的互换关系找出服务端自动生成的对称列再把它重命名为 JSON 中记录的原始标题v1SymmetricColumn.title——这一步保证导入后的界面标题与源 Base 一致rootLinks记录每个成功创建的链接连同源表一起入队供最后的数据关系修复restoreLinks使用。4.3 Lookup / Rollup / Formula 的 ID 重映射Lookup 与 Rollup 创建前必须把 JSON 里的 v1 ID 翻译成 v2 ID换算函数是get_v2Id()先在 JSON 中按 v1 字段 ID 找到字段 title再在新表中按 title 找到对应列的 v2 ID。Rollup 额外带上rollup_function聚合函数。Formula 则只回写formula_raw公式文本由服务端重新解析生成 SQL。脚本文件头部注释明确列出了两个已知边界tbd公式依赖列表与嵌套 Lookup/Rollup尚未完整处理即公式若引用了 Lookup/Rollup 列或跨表嵌套引用时可能失败使用时需人工验证。4.4 视图重建Grid / Gallery / FormconfigureGrid()每张表新建表时 NocoDB 自带一个默认 Grid 视图脚本把第一个导出 Grid 直接重命名为默认视图api.dbView.update其余用api.dbView.gridCreate创建。随后逐列更新可见性show、顺序order、列宽gridColumnUpdate再逐条创建排序dbTableSort.create携带direction与过滤dbTableFilter.create。从源码看过滤条件列名反查时误用了sort[fCnt].fk_column_idimportSchema.js 该处属于脚本遗留缺陷过滤列与排序列不一致时可能定位错列实际使用中建议核对过滤结果。configureGallery()逐个api.dbView.galleryCreate创建同名视图当前实现仅还原标题未迁移封面图配置。configureForm()api.dbView.formCreate时携带导出的propertyheading、subheading、success_msg、redirect_after_secs、email、submit_another_form、show_blank_form 等然后逐列更新表单列的show/order/label/description/required列 ID 通过nc_getViewColumnId()用fk_column_id在新视图的列集合中反查获得。4.5 数据回迁从源 Base 实时分页复制这是 ReadMe.md 中数据导入不经过导出 JSON的具体实现。当api.base.list()里能找到源 BasesrcProject时脚本执行restoreBaseData()restoreLinks()restoreBaseData()以 25 条为一页limit25, offset递增循环api.dbTableRow.list(nc, srcProject, 表名, ...)直到pageInfo.isLastPage每条记录再用主键pk字段 titleread出完整数据然后删除 Link/Lookup/Rollup 字段的值这些字段在目标端会自动计算或由后续步骤恢复最后api.dbTableRow.create(nc, baseName, 表名, record)写入新 BaserestoreLinks()遍历rootLinks同样分页读取源表记录取出链接字段值用api.dbTableRow.nestedAdd(...)在新 Base 中逐条把链接关系挂回nestedAdd是 nocodb-sdk Api 提供的嵌套关联操作用于在记录上追加关联行 ID。由于数据是通过 REST API 逐行读写的这个流程是结构性迁移 API 数据搬运的组合方案源 Base 必须可达、令牌必须对源/目标都有读写权限若源 Base 不存在则只做纯结构迁移。五、使用限制与排错清单结合 ReadMe.md 与两份脚本源码可以确认的边界条件导出文件名约定导出产物固定为srcProject.json空格转下划线导入时srcProject配置值必须与该文件名去.json一致jsonfile.readFileSync是按此拼接的dstProject同名的旧 Base 会被删除importSchema()开头if (p) await api.base.delete(p.id)重复执行导入前请确认目标 Base 中无需要保留的数据mm 链接列只建一侧导入靠isLinkCreated判重一张多对多关系在目标端只由一侧触发创建另一侧对称列由服务端自动生成后被改名对齐公式与嵌套引用是已知缺口脚本头部tbd注释声明未处理 formula 依赖列表与嵌套 lookup/rollupGallery 视图迁移不完整导出保留了封面图字段信息但configureGallery()目前只创建同名视图认证失败xc-auth为占位符或过期会导致所有 SDK 调用报错脚本仅console.log错误无重试数据回迁的前提源 Base 存在于同一实例且令牌可读行数据按主键逐条 read 逐条 create大批量数据下速度受 API 往返限制每页 25 条。六、小结这套脚本给出了 NocoDB 基于公开 REST API 做 Base 级迁移的完整参考实现导出端以名称映射表 分类型字段裁剪生成可移植的 schema JSON导入端以普通字段 → 链接 → Lookup → Rollup → Formula → 视图 → 数据 → 关系数据的依赖顺序重建结构并用 title 作为跨实例 ID 重映射的锚点。对于需要程序化克隆、备份或跨环境部署 NocoDB Base 结构的场景exportSchema.js 与 importSchema.js 中api.dbTable.*、api.dbView.*、api.dbTableRow.nestedAdd等 SDK 调用链本身就是最可靠的 API 用法示例使用时应结合第五节的限制清单对公式依赖、Gallery 配置与批量数据耗时做针对性验证。【免费下载链接】nocodb A Free Self-hostable Airtable Alternative项目地址: https://gitcode.com/GitHub_Trending/no/nocodb创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表