后端数据库GraphQL【免费下载链接】prisma1 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL MongoDB) [deprecated]项目地址https://gitcode.com/gh_mirrors/pr/prisma1点击查看免费下载本指南以 Prisma 1.x 系列当前仓库 docs/1.2/04-Reference/03-Prisma-API/04-Mutations.md为基础系统讲解 Prisma GraphQL API 中三类变更操作对象变更Object mutations、嵌套变更Nested mutations与批量变更Batch mutations并覆盖标量列表scalar list字段的特殊变更语法。阅读完成后你将能够根据 数据模型.md) 自动生成的 API 编写出可正确创建、更新、upsert、删除单节点以及跨关系批量操作节点的 mutation并理解其底层执行约束如嵌套 upsert 限制、批量变更不触发订阅等。Mutations 总览Prisma API 由服务的数据模型data model自动生成其 mutation 分为三类简单变更Simple mutations对某个对象类型执行单节点的create、update、upsert与delete批量变更Batch mutations对某个模型的多个节点同时执行update与delete关系变更Relation mutations跨关系对节点执行connect、disconnect、create、update与upsert。在服务端实现中这些顶层 mutation 分别对应 Create.scala、Update.scala、Upsert.scala、Delete.scala、UpdateMany.scala 与 DeleteMany.scala 等ClientMutation子类由 ClientMutationRunner.scala 统一调度执行。可以使用 GraphQL Playground 探索你服务中实际的 mutation 操作。下面所有示例均基于以下数据模型type Post { id: ID! unique title: String! published: Boolean! author: User! } type User { id: ID! unique age: Int email: String! unique name: String! posts: [Post!]! }User.email与User.id均以unique指令标注因此它们都可以作为节点选择node selection的唯一标识使用。对象变更Object mutations对象变更用于修改某个模型的单个节点。创建节点create使用createUser创建新用户# Create a new user mutation { createUser( data: { age: 42 email: zeusexample.com name: Zeus } ) { id name } }注意所有没有 默认值.md) 的必填字段都必须出现在data输入对象中否则请求会因校验失败被拒绝。例如上述模型中User.email、User.name以及Post.title、Post.published都是必填字段。在服务端create 请求经 Create.scala 将原始参数解析为CoolArgs再交由 DatabaseMutactions.scala 生成对应的数据库写操作。更新节点update使用updateUser修改email和name。注意这里通过where参数进行 节点选择mutation { updateUser( data: { email: zeus2example.com name: Zeus2 } where: { email: zeusexample.com } ) { id name } }更新操作同样基于where中的唯一字段定位节点服务端 Update.scala 中通过CoolArgs(args.raw).extractNodeSelectorFromWhereField(model)从where字段提取NodeSelector再生成更新 mutaction。Upsert 节点当希望“要么更新已有节点、要么创建新节点”时可以使用 upsert mutation——无论哪种结果都在单次 mutation 中完成# Upsert a user mutation { upsertUser( where: { email: zeusexample.com } create: { email: zeusexample.com age: 42 name: Zeus } update: { name: Another Zeus } ) { name } }注意create和update参数的类型分别与createUser中的data对象、updateUser中的data对象相同。注意当前版本不支持在 upsert 内包含嵌套变更嵌套在 upsert 中的嵌套变更会被忽略。参见相关 issue 讨论#1579 与 #2194。从源码实现看upsert 由 Upsert.scala 处理其行为取决于where是否命中已有节点命中则执行update分支未命中则执行create分支。删除节点delete删除节点只需在deletemutation 中 选择待删除的节点。按id删除mutation { deleteUser(where: { id: cjcdi63l20adx0146vg20j1ck }) { id name email } }由于email同样标注了unique.md) 指令也可以用email选择进而删除User节点mutation { deleteUser(where: { email: cjcdi63l20adx0146vg20j1ck }) { id name email } }where中凡是带有unique的标量字段都可作为唯一选择器这也是 Prisma 自动生成输入类型如 InputTypesBuilder.scala 中所定义时区分“唯一选择”与“普通过滤”的依据。嵌套变更Nested mutationscreate 和 update 模型变更可以同时跨关系修改节点这被称为嵌套变更并以事务方式执行——要么全部成功要么全部回滚。可用嵌套参数概览嵌套变更支持以下参数createupdateupsertdeleteconnectdisconnect这些参数是否可用以及具体行为取决于两个维度父变更的类型create mutation、update mutation 还是 upsert mutation关系的类型可选 to-one 关系、必填 to-one 关系、to-many 关系。例如create mutation 只暴露嵌套的create与connectupdate mutation 对必填 to-one 关系暴露update、upsert等操作。服务端通过 NestedMutations.scala 将嵌套参数建模为NestedMutations结构内部以creates、updates、upserts、deletes、connects、sets、disconnects、updateManys、deleteManys九类操作向量承载每一种操作进一步细分为“按关系定位”与“按唯一 where 定位”两种形态如UpdateByRelation与UpdateByWhere、UpsertByRelation与UpsertByWhere、DeleteByRelation与DeleteByWhere。仓库中还有大量针对嵌套变更组合行为的测试例如 NestedConnectMutationInsideCreateSpec.scala、NestedDeleteMutationInsideUpdateSpec.scala 等可用来验证不同关系约束下的行为。创建并连接相关节点在嵌套输入对象字段中使用connect操作可以连接一个或多个已存在的相关节点。下面创建一个新的Post并通过唯一字段email连接到已存在的author。此时connect提供了一种节点选择方式# Create a post and connect it to an author mutation { createPost(data: { title: This is a draft published: false author: { connect: { email: zeusexample.com } } }) { id author { name } } }如果在author中提供create参数而非connect则会_创建_一个相关的author并同时与之连接而不是连接已存在的 author。由于User与Post是 to-many 关系创建User时可以同时create和connect多个Post节点。下面创建一个新User同时新建多个Post并连接已有的Post# Create a user, create and connect new posts, and connect to existing posts mutation { createUser( data: { email: zeusexample.com name: Zeus age: 42 posts: { create: [{ published: true title: First blog post }, { published: true title: Second blog post }] connect: [{ id: cjcdi63j80adw0146z7r59bn5 }, { id: cjcdi63l80ady014658ud1u02 }] } } ) { id posts { id } } }更新与 upsert 相关节点更新节点时可以同时更新一个或多个相关节点mutation { updateUser( data: { posts: { update: [{ where: { id: cjcf1cj0r017z014605713ym0 } data: { title: Hello World } }] } } where: { id: cjcf1cj0c017y01461c6enbfe } ) { id } }注意update接受一个对象列表每个对象包含where和data字段与updatePostmutation 的参数形式一致。嵌套 upsert 的用法类似mutation { updatePost( where: { id: cjcf1cj0r017z014605713ym0 } data: { author: { upsert: { where: { id: cjcf1cj0c017y01461c6enbfe } update: { email: zeus2example.com name: Zeus2 } create: { email: zeusexample.com name: Zeus } } } } ) { id } }删除相关节点更新节点时可以同时删除一个或多个相关节点。此时delete同样提供节点选择能力mutation { updateUser( data: { posts: { delete: [{ id: cjcf1cj0u01800146jii8h8ch }, { id: cjcf1cj0u01810146m84cnt34 }] } } where: { id: cjcf1cj0c017y01461c6enbfe } ) { id } }关系约束会在嵌套变更执行前被校验仓库测试 NestedConnectMutationInsideCreateSpec.scala 展示了“必填关系被破坏”的场景会以错误码 3042 拒绝The change you are trying to make would violate the required relation ...同时保证数据库状态不变印证了嵌套变更的事务语义。标量列表变更Scalar list mutations当 对象类型.md) 的某个字段是_标量列表_类型时会有一批特殊的变更操作可用。下面数据模型中User有三个这样的字段type User { id: ID! unique scores: [Int!]! # scalar list for integers friends: [String!]! # scalar list for strings coinFlips: [Boolean!]! # scalar list for booleans }注原始文档示例中写的是throws字段名但按数据模型定义应为coinFlips这里以模型定义为准。创建节点时的标量列表创建User节点时可以用set为每个标量列表字段提供一组值mutation { createUser(data: { scores: { set: [1, 2, 3] } friends: { set: [Sarah, Jane] } coinFlips: { set: [false, false] } }) { id } }更新节点时的标量列表更新已有User节点时对标量列表字段可以执行以下操作set用全新列表覆盖现有列表。push即将推出在列表任意位置添加一个或多个元素。pop即将推出从列表开头或末尾移除一个或多个元素。remove即将推出移除列表中匹配给定过滤条件的所有元素。注意push、pop、remove尚未实现。如果想了解它们未来的形态可以查看对应的规格讨论#1275。服务端当前仅实现了set操作对应 NestedMutations.scala 中的ScalarListSet(values: Vector[Any])InputTypesBuilder.scala在构建模型的输入类型时也会扫描model.scalarListFields来生成对应的输入结构。set示例在 update mutation 中每个标量列表字段接受一个包含set字段的对象其值可以是单个标量值_或_该标量类型的列表。将已有User节点的scores设为[1]mutation { updateUser( where: { id: cjd4lfdyww0h00144zst9alur } data: { scores: { set: 1 } } ) { id } }将scores设为[10,20,30]mutation { updateUser( where: { id: cjd4lfdyww0h00144zst9alur } data: { scores: { set: [10,20,30] } } ) { id } }批量变更Batch mutations批量变更用于一次更新或删除大量节点返回数据只包含受影响的节点数count。更新大量节点时用where参数选择受影响节点用data指定新值所有节点会被更新为相同的值注意批量变更不会触发任何订阅事件下面将所有 2017 年创建、尚未发布的Post节点发布mutation { updateManyPosts( where: { createdAt_gte: 2017 createdAt_lt: 2018 published: false } data: { published: true } ) { count } }下面删除某个author的所有未发布Post节点mutation { deleteManyPosts( where: { published: false author: { name: Zeus } } ) { count } }服务端实现中批量更新由 UpdateMany.scala 处理它持有whereFilter: Option[Filter]作为过滤条件通过getMutactionsForUpdateMany生成数据库 mutaction并以BatchPayload(count ManyHelper.getManyCount(results))作为返回值——这正是 mutation 结果中count的来源。由于批量变更绕过单节点变更路径因此不会产生订阅事件。小结Prisma 的 mutation API 围绕数据模型自动生成覆盖了从单节点创建/更新/upsert/删除到跨关系嵌套变更再到面向海量数据的批量变更的完整写操作矩阵。使用时需要记住几个关键约束必填且无默认值的字段必须在create的data中显式给出where仅接受unique字段作为唯一节点选择器嵌套connect/update/delete同样遵循该规则嵌套变更整体以事务方式执行关系约束违规如错误码 3042会导致整个变更回滚嵌套变更目前不能放在 upsert 内部使用批量变更不触发订阅事件且所有目标节点被更新为同一组值标量列表字段的push/pop/remove尚未实现目前只能使用set。如需深入验证这些行为可以结合仓库中的 API 测试用例如 server/servers/api/src/test/scala/com/prisma/api/mutations 目录下的嵌套变更与批量变更 Spec以及 服务端 Schema 定义 查看完整 mutation 形态。赞分享后端数据库GraphQL【免费下载链接】prisma1 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL MongoDB) [deprecated]项目地址https://gitcode.com/gh_mirrors/pr/prisma1点击查看免费下载相关推荐Prisma Mutations 完全指南单对象、嵌套与批量变更操作详解Prisma Mutations 完全指南单对象、嵌套与批量变更操作详解 本篇技术指南以 Prisma 官方文档《Mutations》为核心系统讲解 Pri后端数据库GraphQLPrisma Mutations 完全指南对象、嵌套与批量变更操作深入解析Prisma Mutations 完全指南对象、嵌套与批量变更操作深入解析 Prisma API 将服务数据模型data model自动生成一组完整的 G后端数据库GraphQLPrisma API 变更操作Mutations完整指南对象、嵌套、标量列表与批量变更实战Prisma API 变更操作Mutations完整指南对象、嵌套、标量列表与批量变更实战 本文围绕 Prisma 1.x 服务自动生成的 GraphQL后端数据库GraphQL创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考