无法将时间和数据作为输入并写入使用 Hasura GraphQL 实现的数据库
Posted
技术标签:
【中文标题】无法将时间和数据作为输入并写入使用 Hasura GraphQL 实现的数据库【英文标题】:Unable to take time and dat as input and write into database implemented using Hasura GraphQL 【发布时间】:2021-02-16 13:20:12 【问题描述】:我正在尝试使用 React 和 Hasura GraphQL 创建一个非常简单的 3 页日程管理应用程序。我将所有已安排的会议显示为一页,我将会议的标题、日期和参与者人数作为用户的输入,并将用户发送到下一页以输入会议的开始和结束时间。但是,当我尝试将输入的值写入数据库时,我收到一条错误消息:
variable startTime of type String! is used in position expecting time
和
variable date of type String! is used in position expecting Date
我不确定日期和时间是否是架构中的预期数据类型,我可以在编写查询时使用。我还附上了两个输入页面的代码,让您了解我现在做错了什么。
这是我的第一个输入页面:
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import Form from 'react-bootstrap/Form'
import Button from 'react-bootstrap/Button';
import Link from "react-router-dom";
import withRouter from 'react-router-dom'
class NewSchedulePageFirst extends React.Component
constructor(props)
super(props);
this.state=
title: "",
date: "",
participants: ""
this.handleChange=this.handleChange.bind(this);
handleChange(event)
const name, value = event.target
this.setState(
[name]: value
)
render()
return (
<div className="form">
<div className="form-title">
<h2>Enter details for new entry </h2>
</div>
<div className="form-fields">
<Form>
<div className="form-title">
<Form.Control type="text" placeholder="Title" onChange=this.handleChange value=this.state.title name="title" />
</div>
<div className="form-date">
<Form.Control type="date" onChange=this.handleChange value=this.state.date name="date" />
</div>
<div className="form-participants">
<Form.Control type="number" placeholder="No. of participants" onChange=this.handleChange value=this.state.participants name="participants" />
</div>
</ Form>
</div>
<Link to=
pathname: "/NewSchedulePageTwo",
state :
title: this.state.title,
date: this.state.date,
participants: this.state.participants
>
<Button variant="outline-primary"> Next </Button>
</Link>
</div>
);
export default withRouter(NewSchedulePageFirst) ;
这是我尝试将数据写入数据库的第二页:
import React, useState from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import Form from 'react-bootstrap/Form'
import Button from 'react-bootstrap/Button';
import GET_MY_SCHEDULE from './currentscheduledisplay'
import Link , withRouter from "react-router-dom";
import gql from "@apollo/client";
import useMutation from "@apollo/client";
const ADD_SCHEDULE = gql `
mutation($title: String!, $date: String!, $startTime: String!, $endTime: String!, $participants: Int!)
insert_Schedule(objects: title: $title, date: $date, startTime: $startTime, endTime: $endTime, participants: $participants )
affected_rows
returning
id
title
date
startTime
endTime
participants
`;
function NewSchedulePageSecond(props)
// console.log(props.location.state);
const title, date, participants = props.location.state;
const [ stitle, setStitle ] = useState(title);
const [ sdate, setSdate ] = useState(date);
const [ sparticipants, setSparticipants ] = useState(participants);
const [ startTime, setStartTime ] = useState('');
const [ endTime, setEndTime ] = useState('');
// handleChange(event)
// const name, value = event.target
// this.setState(
// [name]: value
// )
//
// scheduleInput(event)
// const value = event.target;
// this.setState(schedule : value);
//
// componentDidMount()
//
const resetInput = () =>
setStitle(title);
setSdate(date);
setSparticipants(participants);
setStartTime('');
setEndTime('');
const updateCache = (cache, data) =>
// Fetch the todos from the cache
const existingSchedule = cache.readQuery(
query: GET_MY_SCHEDULE
);
// Add the new todo to the cache
const newSchedule = data.insert_todos.returning[0];
cache.writeQuery(
query: GET_MY_SCHEDULE,
data: schedule: [newSchedule, ...existingSchedule.schedule]
);
;
const [addSchedule] = useMutation(ADD_SCHEDULE, update: updateCache, onCompleted: resetInput );
return (
<div className="form">
<div className="form-title">
<h2>Enter details for new entry </h2>
</div>
<div className="form-fields">
<Form>
<div className="form-start-time">
<Form.Control type="time" onChange=(e) => setStartTime(e.target.value) value=startTime name="startTime" />
</div>
<div className="form-end-time">
<Form.Control type="time" onChange=(e) => setEndTime(e.target.value) value=endTime name="endTime" />
</div>
</ Form>
</div>
<Link to='/'>
<Button variant="outline-primary" onClick=() => addSchedule(
variables: title: stitle,
date: sdate,
participants: sparticipants,
startTime: startTime,
endTime: endTime
)>
Create
</Button>
</Link>
/* <p>
Title: title
</p>
<p>
Date: date
</p> */
</div>
);
export default withRouter(NewSchedulePageSecond);
我的关系的架构如下:
id - integer, primary key, unique, default: nextval('"Schedule_id_seq"'::regclass)
title - text, default: 'Meeting'::text
participants - integer, default: 2
startTime - time without time zone
endTime - time without time zone
date - text, default: 'No Date Entered'::text
我无法找到表示日期和时间的方法。我是第一次使用 GraphQl,所以如果你能解释为什么我也会收到这个错误,那就太好了。
编辑:我的突变如下:
mutation($title: String!, $date: String!, $startTime: String!, $endTime: String!, $participants: Int!)
insert_Schedule(objects: title: $title, date: $date, startTime: $startTime, endTime: $endTime, participants: $participants )
affected_rows
returning
id
title
date
startTime
endTime
participants
【问题讨论】:
'insert_Schedule' 变异 server 签名?参数类型? @xadm 这些是我的表 'Schedule' 中的属性:- id - 整数、主键、唯一,默认值:nextval('"Schedule_id_seq"'::regclass) title - 文本,默认值: 'Meeting'::text 参与者 - 整数,默认:2 startTime - 不带时区的时间 endTime - 不带时区的时间 date - 文本,默认:'No Date Entered'::text 我不关心 DB .... 在 graphiql/playground 中测试您的查询 ... docs explorer 再次显示类型 defs ...,这个突变 def 和参数类型的外观如何 - 自定义日期和时间标量...传递参数[格式]匹配这些标量要求 @xadm 这正是我正在努力解决的问题,如果您能更具体地说明我应该做什么来解决这个问题,那就太好了。我只是在学习 GraohQL,所以如果你能解释显而易见的事情,那就太好了。 检查 SERVER 突变规范,您的 CLIENT 突变必须与 SERVER defs/arg 类型匹配...您可以在 graphiql/playground 文档中检查...或自定义类型 defs 和突变定义输入和返回类型,显示这个,而不是你怎么称呼它,是早知道的 【参考方案1】:您收到此错误是因为在您的 GraphQL 突变中,您将变量指定为 String!
类型,然后在需要 Date
的地方使用它。
例如,假设您有一个名为 update_event
的突变,其期望和参数 time
的类型为 Date
,您的突变应如下所示:
mutation ($time: Date)
update_event(time: $time)
id
而不是
mutation ($time: String!)
update_event(time: $time)
id
在这两种突变中,update_event
期望参数$time
时间为Date
。在第一个突变中,它是一个Date
在第二个突变中,它是一个String!
。第一个是正确的,第二个会失败。
在你的情况下,你有突变:
mutation($title: String!, $date: String!, $startTime: String!, $endTime: String!, $participants: Int!)
insert_Schedule(objects: title: $title, date: $date, startTime: $startTime, endTime: $endTime, participants: $participants )
affected_rows
returning
# ...
您将所有参数类型指定为 String!
,但根据错误,endTime
和 startTime
需要指定为 time
:
mutation($title: String!, $date: String, $startTime: time, $endTime: time, $participants: Int!)
insert_Schedule(objects: title: $title, date: $date, startTime: $startTime, endTime: $endTime, participants: $participants )
affected_rows
returning
# ...
【讨论】:
我已将我的突变添加为我的代码的一部分,但我也会明确添加它。当我尝试将变量的类型指定为时间(对于 startTime 和 endTime)和日期(对于日期)时,它会抛出一个错误,提示“未处理的拒绝(错误):架构中不存在此类类型:'时间''我是不知道为什么。 是的,很抱歉我最初错过了它。过了一会儿我看到它并修改了我的答案。另外,我现在看到您指定了数据库字段类型。所以你有startTime
是time without time zone
,endTime
是time without time zone
和date
是text
。查看此表 hasura.io/docs/1.0/graphql/core/api-reference/… 并使用相应的 GraphQL 类型。所以对于前两个,对应的类型是Implicit
(不知道为什么,从来没有使用过),对于DB text
类型,对应的类型是String
另外,我强烈建议先使用 Hasura 控制台中的“GraphiQL”页面测试您的突变并确保它有效。它会对您有很大帮助。您知道那在哪里吗?
刚刚在我的 Hasura 中对其进行了测试,看起来如果您有一个 time without time zone
字段,则突变中预期的相应类型是 time
。我更新了我的答案。它可能需要time!
是数据库字段不可为空。
在date
字段上也会出错,因为您将String!
指定为类型,但它是一个可为空的字段,因此它必须是String
。也更新了答案。以上是关于无法将时间和数据作为输入并写入使用 Hasura GraphQL 实现的数据库的主要内容,如果未能解决你的问题,请参考以下文章
无法使用我的突变在 Hasura / GraphQL 中插入数组关系
无法连接到 Hasura PostGreSQL docker 容器的 Web 套接字