Prisma:字段...未在...输入类型或类型中定义...预期但未提交对象
Posted
技术标签:
【中文标题】Prisma:字段...未在...输入类型或类型中定义...预期但未提交对象【英文标题】:Prisma: Field ... is not defined in ... input type OR type ... expected but non object was submitted 【发布时间】:2019-11-30 11:47:40 【问题描述】:我正在使用 Prisma 1.34。来自 API 开发。通过 localhost 游乐场对其进行测试。 抱歉,提前写了很长的文字,不明白我哪里出错了。
我有以下表示层次结构的方案脚本模板由卡片模板组成,卡片包括任务模板:
type ScriptTemplate
id: ID!
name: String!
cards: [CardTemplate!]
input: String!
output: String!
type CardTemplate
id: ID!
title: String!
description: String
tasks: [TaskTemplate!]
input ExistingCardTemplateInput
id: ID!
input NewCardTemplateInput
title: String!
description: String!
tasks: [NewTaskTemplateInput!]
type TaskTemplate
id: ID!
label: String!
description: String!
cards: [CardTemplate!]
input ExistingTaskTemplateInput
id: ID!
input NewTaskTemplateInput
label: String!
description: String!
对应的突变是:
type Mutation
createScriptTemplate(name: String!, input: String!, output: String!, cards: [ExistingCardTemplateInput!], new_cards: [NewCardTemplateInput!]): ScriptTemplate
createCardTemplate(title: String!, description: String! tasks:[ExistingTaskTemplateInput!], new_tasks:[NewTaskTemplateInput!]): CardTemplate
createTaskTemplate(label: String!, description: String! cards:[ExistingCardTemplateInput!]): TaskTemplate
所以基本上,如果我尝试使用 createTaskTemplate
突变或 createCardTemplate
突变 - 一切正常。我可以创建这些实体,包括使用其中的新任务创建新卡的嵌套突变或绑定现有任务。或现有卡到新创建的任务。这就是明确定义输入类型的原因:ExistingTaskTemplateInput
、NewTaskTemplateInput
和 NewCardTemplateInput
。
当我尝试创建包含新卡或将其连接到现有卡的新脚本时,一切都按预期工作。
但是,如果我尝试创建脚本、卡片并在其中包含新任务,我会收到上面的错误消息。
-
尝试以下突变时:
mutation
createScriptTemplate(
name: "Script via API_H2"
input: "Something describing initial state"
output: "Something describing required state at the end"
cards: [
id: "cjycl2nup00ta0703sd0kd8oa"
,
id: "cjye3ryee01ey070383sxaoxz"
]
new_cards:[
title:"New card via scriptis2"
description:"desc"
tasks: [
description: "test dewscription"
label: "test label"
]
,
title:"New card through scriptos2"
description: "desc"
]
)
id
name
input
output
createdAt
updatedAt
cards
id
title
tasks
id
label
我有错误:
"data":
"createScriptTemplate": null
,
"errors": [
"message": "Variable '$data' expected value of type 'ScriptTemplateCreateInput!' but got:
\"name\":\"First Script through API_H2\",\"input\":\"Something describing initial state\",\"output\":\"Something describing requred state at the end\",\"cards\":\"connect\":[\"id\":\"cjycl2nup00ta0703sd0kd8oa\",\"id\":\"cjye3ryee01ey070383sxaoxz\"],\"create\":[\"title\":\"New card via scriptis2\",\"description\":\"desc\",\"tasks\":[\"label\":\"test label\",\"description\":\"test dewscription\"],\"title\":\"New card through scriptos2\",\"description\":\"desc\"].
Reason: 'cards.create[0].tasks'
Expected 'TaskTemplateCreateManyWithoutCardsInput', found not an object. (line 1, column 11):\nmutation ($data: ScriptTemplateCreateInput!) \n ^",
"locations": [
"line": 2,
"column": 3
],
"path": [
"createScriptTemplate"
]
]
实际请求如下所示(通过 console.log):
name: 'First Script through API_H2',
input: 'Something describing initial state',
output: 'Something describing requred state at the end',
cards:
connect:
[ [Object: null prototype] id: 'cjycl2nup00ta0703sd0kd8oa' ,
[Object: null prototype] id: 'cjye3ryee01ey070383sxaoxz' ],
create:
[ [Object: null prototype]
title: 'New card via scriptis2',
description: 'desc',
tasks:
[ [Object: null prototype] label: 'test label', description: 'test dewscription' ] ,
[Object: null prototype] title: 'New card through scriptos2', description: 'desc' ]
看起来我缺少 tasks
字段的 connect or create 位。
但是,当我将其更改为:
tasks: create: [
description: "test dewscription"
label: "test label"
]
Field \"create\" is not defined by type NewTaskTemplateInput
和 Field NewTaskTemplateInput.label and description of required type String! was not provided
出现错误
-
但是,这完全可以正常工作(没有任务的相同请求):
mutation
createScriptTemplate(
name: "Script via API_H2"
input: "Something describing initial state"
output: "Something describing required state at the end"
cards: [
id: "cjycl2nup00ta0703sd0kd8oa"
,
id: "cjye3ryee01ey070383sxaoxz"
]
new_cards:[
title:"New card via scriptis2"
description:"desc"
,
title:"New card through scriptos2"
description: "desc"
]
)
id
name
input
output
createdAt
updatedAt
cards
id
title
tasks
id
label
检查生成的方案,在那里找不到任何问题。
input TaskTemplateCreateManyWithoutCardsInput
create: [TaskTemplateCreateWithoutCardsInput!]
connect: [TaskTemplateWhereUniqueInput!]
input TaskTemplateCreateWithoutCardsInput
id: ID
label: String!
description: String!
看起来我混淆了我在 gql 文件中定义的方案和我再次提出请求的方案,但不知道该往哪个方向发展。
【问题讨论】:
我认为您必须在tasks
中使用带有标签和描述的 create
,或者在 connect
中仅使用 id
。在这里,您使用 connect
带有标签和描述,没有 id。
@Errorname 对不起,我的错误示例。与“创建”相同的结果并不重要。我无法理解的是,因为我将tasks
的输入类型明确定义为[NewTaskTemplateInput!]
。为什么 Prisma 有时会根据这种类型检查它,但同时会根据 TaskTemplateCreateWithoutCardsInput
来检查它?
【参考方案1】:
说明
首先概述一个请求的整个过程。
上图取自 Prisma 官方文档中的 Prisma Basics。
如图,localhost playground
就是图中的client
。 localhost playground
访问的Server
就是图中的API Server
,也就是Prisma Client
。这里是第一个连接,图中绿色箭头。
Prisma Client
通过访问Prisma Server
从数据库中获取数据。这是第二个连接,图中黄色箭头。
数据流的过程,从localhost playground
发送到API Server
完成第一次连接传输,再经过resolve
处理,使用Prisma Client
发送到Prisma Server
完成第二次连接传输。 Prisma Server
根据请求的数据从Database
中检索数据并返回给API Server
,完成第二次连接接受。 API Server
将数据返回给localhost playground
,完成第一次连接的接受。一个完整的过程就完成了。
在使用Prisma
的过程中,我们定义了两种schema,一种用于定义Prisma Server
,名称通常为datamodel.prisma
。另一种用于定义Prisma Client
,如果定义在文件中,通常命名为schema.graphql
,也可以通过模板字符串在JS文件中定义,还有其他方式,这里不深入讨论。您展示的内容属于Client Schema
。
成功完成这个过程需要每个部分发送的数据都是正确的。
您的第一个错误发生在发送第二个连接时。从API Server
发送的数据与Prisma Server
中的架构定义不匹配。
第二个错误是localhost playground
发送的数据与发送第一个连接时API Server
中的schema定义不匹配。
示例
假设以下架构
# datamodel.prisma
type User
id: @id!
name: String!
post: [Post!]!
type Post
id: @id!
title: String!
# schema.graphql
input CreatePost
title: String!
type Mutation
createUser(name: String!,posts:[CreatePost])
使用以下变异创建用户
mutation
createUser(name: "prisma", posts: [ title: "test" ])
id
name
当从localhost playground
发送到API Server
时,数据如下
"name": "prisma",
"posts": [ "title": "test" ]
如果将此数据直接发送给Prisma Server
,则不符合Prisma Server
的定义。您需要将数据转换为符合Prisma Server
架构的定义。
"name": "prisma",
"posts": "create": [ "title": "test" ]
然后通过Prisma Client
发送给Prisma Server
。
const resolve =
Mutation:
createUser: async (_, args) =>
const userCreateInput =
name: args.name,
posts:
create: args.posts,
,
return await prisma.createUser(userCreateInput)
,
,
这样最终数据通过Prisma Server
到达数据库。
解决问题
查看API Server
中createScriptTemplate
的定义,应该是没有将接收到的数据转换成API Server
要求的格式导致的错误。
Understand Prisma
【讨论】:
以上是关于Prisma:字段...未在...输入类型或类型中定义...预期但未提交对象的主要内容,如果未能解决你的问题,请参考以下文章
PRISMA:如何在 prisma 常规类型中跳过 id 字段?