无法将时间和数据作为输入并写入使用 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!,但根据错误,endTimestartTime 需要指定为 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)和日期(对于日期)时,它会抛出一个错误,提示“未处理的拒绝(错误):架构中不存在此类类型:'时间''我是不知道为什么。 是的,很抱歉我最初错过了它。过了一会儿我看到它并修改了我的答案。另外,我现在看到您指定了数据库字段类型。所以你有startTimetime without time zoneendTimetime without time zonedatetext。查看此表 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 套接字

如何仅查询这些对象,这些对象包含使用 Hasura 作为变量给出的数组中的每个元素?

我可以将非 unicode 数据类型写入 Excel 吗?

Hasura 上的客户端数据备份

为啥我使用 graphql > hasura > postgres 保存日期时出错