ARTICLE DETAIL

资讯详情

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

Prisma 数据导出与导入实战:基于 NDF 规范化数据格式的 prisma export / import 全流程指南

Prisma 数据导出与导入实战:基于 NDF 规范化数据格式的 prisma export / import 全流程指南 后端数据库GraphQL【免费下载链接】prisma1 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL MongoDB) [deprecated]项目地址https://gitcode.com/gh_mirrors/pr/prisma1点击查看免费下载导读Prisma 为数据迁移、环境克隆与测试数据复用提供了一套内置的数据导入导出能力其核心是名为Normalized Data FormatNDF规范化数据格式的中间格式无论底层是 SQL、MongoDB 还是 JSON 数据源数据都会先被转换成 NDF再以分块上传的方式写入 Prisma 服务。本文将基于 Prisma 1.12 文档与仓库源码完整演示「创建服务 → 写入种子数据 → 导出 NDF → 部署到新 stage → 导入 NDF」的实战闭环并深入讲解 NDF 的nodes/lists/relations三种值类型、prisma export与prisma import命令的源码级实现以及原始 HTTP 导入导出 API 的调用方式帮助你安全地在开发、测试与生产环境之间搬运数据。数据导入导出的总体流程一切围绕 NDFPrisma 使用一种专门的中间格式来导入和导出数据Normalized Data FormatNDF。它是一套约束严格的 JSON 结构规范详见 NDF 参考文档。整个数据迁移流程可以概括为两步-------------- ---------------- ------------ | | | | | | | SQL | (1) transform | NDF | (2) chunked upload | Prisma | | MongoDB | --------------- | | ------------------- | | | JSON | | | | | | | | | | | -------------- ---------------- ------------第 1 步transform把数据源SQL、MongoDB、JSON 等转换为 NDF。这一步目前需要手动完成——将原始数据整理成符合 NDF 结构的 JSON 文件。第 2 步chunked upload把 NDF 数据分块上传到目标 Prisma 服务。这一步既可以通过 CLI 命令prisma import完成也可以直接调用服务暴露的原始导入 API。同样的导出就是该流程的逆向Prisma 服务把数据以 NDF 形式写出来通过prisma export或原始导出 API 下载到本地。本文接下来的实战将围绕以下五个步骤展开创建 Prisma 服务为服务写入初始种子数据以 NDF 格式导出数据将服务部署到一个新的 stage以 NDF 格式导入数据实战准备创建 Prisma 服务在终端中进入你选择的目录运行以下命令初始化一个名为import-example的新服务prisma init import-example当 CLI 询问使用哪种模板时选择Minimal setup: database-only纯数据库最小化设置即可。该命令会创建一个名为import-example的新目录其中包含两个关键文件prisma.yml服务的根配置文件声明服务名、stage、数据模型路径、认证与种子脚本等信息datamodel.graphql服务的数据模型定义SDL 格式。为了让后续导入导出演示包含**关系relation**数据接下来修改数据模型。打开datamodel.graphql将内容替换为type User { id: ID! unique name: String! posts: [Post!]! } type Post { id: ID! unique title: String! author: User! }这里定义了User与Post之间的 1-N 关系一个User拥有多个Post每个Post通过author指向其作者。这个关系会在后面的 NDFrelations数据中体现。通过 seed 写入初始数据为了让服务里有可导出的数据需要先写入一些初始数据。在import-example目录内新建一个seed.graphql文件写入如下变更mutationmutation { createUser(data: { name: Sarah, posts: { create: [ { title: GraphQL is awesome }, { title: It really is }, { title: How to GraphQL is the best GraphQL tutorial } ] } }) { id } }这个 mutation 创建了用户 Sarah并连带创建了三篇属于她的文章——一次调用同时写入了节点数据与关系数据。接下来需要告诉 CLI 这个 seed 文件的存在在prisma.yml中设置seed属性。把prisma.yml更新为service: import-example stage: dev datamodel: datamodel.graphql # to enable auth, provide # secret: my-secret disableAuth: true seed: import: seed.graphql配置说明service服务名与初始化时的import-example一致stage当前部署阶段这里是devdatamodel数据模型文件的相对路径disableAuth: true关闭鉴权便于本地演示如需启用认证可取消注释# secret: my-secret并提供密钥seed.import指向种子脚本文件prisma deploy时 CLI 会把seed.graphql中定义的 mutation 发送到服务的 API。执行部署CLI 会同时完成「部署服务」和「执行种子 mutation」两件事prisma deploy当被询问部署到哪个cluster集群时选择一个公共集群选项prisma-eu1或prisma-us1注意使用 Docker 部署同样支持 seeding。部署并播种完成后打开 GraphQL Playground 执行以下查询来验证种子数据是否生效{ users { name posts { title } } }Prisma API 应返回如下数据{ data: { users: [ { name: Sarah, posts: [ { title: GraphQL is awesome }, { title: It really is }, { title: How to GraphQL is the best GraphQL tutorial } ] } ] } }以 NDF 格式导出数据数据就绪后即可执行导出。在import-example目录下运行prisma export命令执行后会在当前目录生成一个名为export-__TIMESTAMP__.zip的压缩文件其中__TIMESTAMP__是导出的精确时间戳例如export-2018-01-13T19:28:25.921Z.zip。压缩包内的文件即 NDF 格式数据。关于导出文件名可以对照 CLI 源码中的默认逻辑导出命令实现 中exportPath this.flags[path] || export-${new Date().toISOString()}.zip即未显式指定路径时默认使用带时间戳的文件名若指定路径不以.zip结尾CLI 会自动补上.zip后缀。源码中该命令还支持--path短参数-p自定义导出文件路径、--env-file-e指定注入环境变量的.env文件、以及--project指定 Prisma 定义文件路径注意在 1.12 参考文档中该参数写作--export-path/-e不同版本间存在参数名差异请以你所安装版本的prisma export --help输出为准。关于 NDF 文件在压缩包内的组织方式参考文档《Data Export》说明导出数据按三种 NDF 类型分别放入nodes、lists、relations三个目录。仓库自带的导出 fixture 正是这一结构的真实样例——导出样例数据 展示了nodes目录下000001.json的内容一个包含valueType: nodes与values数组的 NDF 文档数组内每个元素代表一条记录例如_typeName: Post、id、title、description、state等字段。部署服务到新 stage 以创建克隆环境导出的 NDF 数据可以导入到任何拥有相同数据模型的服务中。最常见的场景之一就是通过「新 stage」创建一个服务的克隆用于测试环境数据准备。打开prisma.yml把stage改为新值例如test同时删除seed和cluster属性service: import-example stage: test datamodel: datamodel.graphql # to enable auth, provide # secret: my-secret disableAuth: true为什么删除seed因为新 stage 的数据将由 NDF 导入提供不需要再次执行种子脚本删除cluster则是让 CLI 重新询问部署目标。再次运行部署命令把服务部署到新的teststageprisma deploy同样地提示选择集群时选择prisma-eu1或prisma-us1。以 NDF 格式导入数据新 stage 运行起来后就可以把之前导出的数据导入进去。运行以下命令将__DATA__占位符替换为导出 zip 文件的实际路径例如export-2018-01-13T19:28:25.921Z.zipprisma import --data __DATA__--data短参数-d是导入命令的必选参数指向包含待导入数据的目录或 zip 文件。从 导入命令实现 可以看到CLI 会先校验路径是否存在Path ${data} does not exist并校验参数要么以.zip结尾、要么是一个目录data must be a directory or end with .zip然后从prisma.yml读取服务名与 stage、获取鉴权 token最终交给Importer执行上传。导入成功后在teststage 的 GraphQL Playground 中再次发送之前的users查询即可验证数据已完整复制到新环境。导入数据的目录规范如果不用 zip而是直接提供一个目录那么目录内的 NDF 文件必须按类型放在nodes、lists、relations三个子目录中。目录与文件命名规则如下详见 Data Import 参考文档NDF 文件是遵循特定结构的 JSON 文件因此每个数据文件必须以.json结尾每个类型目录内的.json文件需从 1 开始递增编号如1.json编号前可以补任意数量的零如01.json或0000001.json每种类型可以上传任意数量的文件但建议每个文件不超过 1 MB否则可能触发超时。一个符合规范的目录结构示例. ├── data │ ├── lists │ │ ├── 0001.json │ │ ├── 0002.json │ │ └── 0003.json │ ├── nodes │ │ ├── 0001.json │ │ └── 0002.json │ └── relations │ └── 0001.json ├── datamodel.graphql └── prisma.yml其中data目录存放待导入数据所有.json文件均遵循 NDF。导入命令为prisma import --data data仓库的导入测试 fixture 完整印证了这一结构导入测试目录 下同时包含lists/000001.json、nodes/000001.json、relations/000001.json与打包好的import.zip可直接作为编写自定义导入数据时的参照。深入 NDF三种值类型与 JSON 结构NDF 的本质是对如何用 JSON 表达图数据的一整套约定。数据被切分为三种value type值类型Nodes节点的**标量字段scalar fields**数据即数据库中的记录本体Lists节点的**列表字段list fields**数据Relations通过**关系字段relation fields**把两个节点连接起来的数据。一个 NDF JSON 文档是一个对象包含且仅包含两个键valueType文档中数据的值类型只能是nodes、lists或relationsvalues实际数据数组其内部结构取决于valueType。下面以这个数据模型为例说明三种值类型的具体写法type User { id: String! unique firstName: String! lastName: String! hobbies: [String!]! partner: User }Nodes节点的标量字段当valueType为nodes时values数组中每个对象的结构为{ valueType: nodes, values: [ { _typeName: STRING, id: STRING, scalarField1: ANY, scalarField2: ANY, ..., scalarFieldN: ANY }, ... ] }其中_typeName和id均为字符串_typeName指数据模型中该 SDL 类型的名称scalarFieldX是该 SDL 类型各标量字段的名称。例如以下文档导入两个User节点的标量值{ valueType: nodes, values: [ {_typeName: User, id: johndoe, firstName: John, lastName: Doe}, {_typeName: User, id: sarahdoe, firstName: Sarah, lastName: Doe} ] }注意id字段在 NDF 中是每个节点的唯一标识对应数据模型中的uniqueid导入时必须保证其唯一性。Lists节点的列表字段当valueType为lists时values数组中每个对象的结构为{ valueType: lists, values: [ { _typeName: STRING, id: STRING, scalarListField: [ANY] }, ... ] }与nodes不同每个对象只能为一个列表字段提供值。例如为两个User节点的hobbies列表字段导入值{ valueType: lists, values: [ {_typeName: User, id: johndoe, hobbies: [Fishing, Cooking]}, {_typeName: User, id: sarahdoe, hobbies: [Biking, Coding]} ] }Relations节点间的关系当valueType为relations时结构与前两种类型有本质区别values中的每个元素本身是一个数组对pair恰好包含两个对象分别描述关系两端的节点{ valueType: relations, values: [ [ { _typeName: STRING, id: STRING, fieldName: STRING }, { _typeName: STRING, id: STRING, fieldName: STRING } ], ... ] }_typeName、id、fieldName均为字符串其中fieldName是该端节点上关系字段的名称。例如通过partner关系字段把两个User节点连接成伙伴关系{ valueType: relations, values: [ [ { _typeName: User, id: johndoe, fieldName: partner }, { _typeName: User, id: sarahdoe, fieldName: partner } ] ] }源码视角export 与 import 命令的实现要点CLI 导出命令导出命令 的实现要点默认输出文件名为export-${new Date().toISOString()}.zip自动补.zip后缀从prisma.yml加载服务名与 stage获取集群信息与鉴权 token通过Exporter类调用服务端导出 API并把下载到的 NDF 数据直接写入本地文件系统导出文件结构参见 导出样例数据命令结束后会打印提示告知可直接用prisma import --data zip把数据导入新服务。CLI 导入命令导入命令 的实现要点--data-d为必选参数且校验必须是存在的路径目录或.zip文件否则直接报错与导出不同导入还会读取datamodel.graphqlthis.definition.typesString并把数据模型传给Importer用于执行基础的校验检查相比直接调用原始 APICLI 导入的优势在于可一次上传多个文件、复用 CLI 的鉴权机制无需手工携带 token、支持导入过程中断点续传pause and resume。重要限制与警示阅读源码可以发现两条必须知晓的限制原文档的 Data Import 参考 与源码行为一致不支持文档型数据库当prisma.yml中databaseType为document即 MongoDB时export/import命令会直接抛出错误提示改用数据库原生的导入导出工具如 mongodump / mongorestore。命令已弃用源码中 export/import 命令会打印黄色警告说明这两个命令未来不会继续开发官方建议在 MySQL / Postgres 场景改用数据库原生的导入导出能力如mysqlimport、pg_restore。因此在为存量数据做迁移规划时应优先评估数据库原生方案。关于幂等性与数据校验导入操作不具备幂等性每次导入都只会向服务追加数据永远不会更新已存在的节点。这意味着对同一数据集重复导入会导致未定义行为undefined behaviour例如用相同的id重复导入同一个节点很可能破坏服务的数据一致性原始导入 API 对数据不做任何校验使用 CLI 导入时才会执行基础校验导入非法数据同样会导致未定义行为服务维护者有责任保证待导入数据的合法性。实用技巧要保证导入数据合法最稳妥的方式是先导后查——在数据模型完全相同的服务上先执行一次 导出以导出的 NDF 文件为模板来核对或生成待导入数据。进阶直接调用原始 HTTP 导入导出 API除 CLI 外还可以绕过 CLI 直接调用服务暴露的原始 HTTP API适合在脚本化、自动化场景中使用。两者的底层是同一套服务端能力区别在于 CLI 额外帮你处理了鉴权、文件落地与游标管理。导出 API原始导出 API 位于服务 HTTP 端点的/export路径下例如http://localhost:60000/my-app/dev/exporthttps://database.prisma.sh/my-app/prod/export单次请求最多可下载10 MB的 NDF JSON 数据请求必须携带Authorization头Bearer token。请求体为 JSON包含fileType与cursor两个字段{ fileType: nodes, cursor: { table: 0, row: 0, field: 0, array: 0 } }cursor中的值描述从数据库何处开始导出。每次导出响应都会返回一个新的 cursor其状态有两种已终止terminated当table、row、field、array全部返回-1表示导出已完成未终止non-terminated当其中任一值不等于-1表示本次响应的 10 MB 上限已满此时应把响应返回的cursor原样用作下一次导出请求的入参循环拉取直到游标终止。一个导出请求的curl示例NDF 类型为nodescurl http://localhost:60000/my-app/dev/export \ -H Content-Type: application/json \ -H Authorization: Bearer __JWT_AUTH_TOKEN__ \ -d {fileType:nodes,cursor:{table:0,row:0,field:0,array:0}} \ -sSv使用占位符的通用写法curl __SERVICE_ENDPOINT__/export \ -H Content-Type: application/json \ -H Authorization: Bearer __JWT_AUTH_TOKEN__ \ -d {fileType:__NDF_TYPE__,cursor: {table:__TABLE__,row:__ROW__,field:__FIELD__,array:__ARRAY__}} \ -sSv导入 API原始导入 API 位于服务 HTTP 端点的/import路径下例如http://localhost:60000/my-app/dev/importhttps://database.prisma.sh/my-app/prod/import单次请求最多可上传10 MB的 NDF JSON 数据同样需要Authorization头。与导出 API 用fileType区分类型不同导入请求体直接使用 NDF 文档本身的valueType与values结构curl http://localhost:60000/my-app/dev/import \ -H Content-Type: application/json \ -H Authorization: Bearer __JWT_AUTH_TOKEN__ \ -d {valueType:__NDF_TYPE__,values: __DATA__ } \ -sSv其中__DATA__是一个符合对应值类型结构的 NDFvalues数组可参考前文三种值类型的 JSON 示例。总结与建议通过本文的完整闭环你已经掌握了 Prisma 数据导入导出的全部核心能力NDF 作为中间格式统一了异构数据源的导入导出prisma export一键把服务数据导出为带时间戳的 zip内含nodes/lists/relations三目录的 NDF 文件修改stage重新部署即可创建一个空的服务克隆prisma import --data把 NDF 数据灌入新环境实现开发、测试环境数据的快速复制。在投入使用前请务必牢记几点实践建议导入不可幂等导入只会追加、不会更新重复导入同一数据集会导致未定义行为请避免对同一服务重复导入先导出、后导入用同构服务导出的 NDF 作为数据模板是保证导入数据合法性的最可靠方式关注大小限制原始 API 单请求上限 10 MBCLI 建议每个 NDF 文件不超过 1 MB超出部分需按目录规范拆分评估替代方案由于 export/import 命令已进入弃用流程且不支持 MongoDBdocument 型数据库对新的数据迁移需求建议优先评估数据库原生导入导出工具。如需继续深入可进一步阅读仓库内的 NDF 规范、导出参考 与 导入参考或直接阅读 导出命令源码、导入命令源码 及其 导入测试样例。赞分享后端数据库GraphQL【免费下载链接】prisma1 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL MongoDB) [deprecated]项目地址https://gitcode.com/gh_mirrors/pr/prisma1点击查看免费下载相关推荐Prisma 数据导入导出全指南NDF 规范、prisma import/export 命令与原始 API 实践Prisma 数据导入导出全指南NDF 规范、 prisma import / export 命令与原始 API 实践 Prisma 服务的数据迁移、环境克隆后端数据库GraphQLPrisma CLI 数据导入实战prisma import 命令与 NDF 规范化数据格式完全指南Prisma CLI 数据导入实战 prisma import 命令与 NDF 规范化数据格式完全指南 本篇指南深入讲解 Prisma CLI 中用于向 Pr后端数据库GraphQLPrisma 数据导出与导入实战基于 NDF 规范化数据格式的完整指南Prisma 数据导出与导入实战基于 NDF 规范化数据格式的完整指南 本文是一份关于 Prisma 服务数据迁移的实战指南核心围绕 Prisma 专用的中后端数据库GraphQL创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表