为了账号安全,请及时绑定邮箱和手机立即绑定

apollo 服务器 + 续集错误非空字段

apollo 服务器 + 续集错误非空字段

森栏 2023-09-28 09:50:29
我正在运行一个apollo 服务器,并将sequelize 作为postgres 数据库的orm。这是架构:    type Tag {        id: ID!        name: String!    }    type Service {        id: ID!        name: String!        slug: String!        tags: [Tag!]!    }解析器:        findServicesByTag: async(_, { tag }, { models }) => {            const res = await models.Service.findAll({                where: {                    '$Tags.name$': tag                }                ,include: [                    {                        model: models.Tag,                        as: 'Tags'                    }                ]            })            console.log(res)            return res        }但是当执行这个查询时query {  findServicesByTag(tag: "restaurant")  {    id name slug    tags {      name    }  }}我收到消息“无法为不可为空的字段 Service.id 返回 null”。console.log 指令打印此数据:[ Service {    dataValues: { id: 1, name: 'Restaurant X', Tags: [Array] },    _previousDataValues: { id: 1, name: 'Restaurant X', Tags: [Array] },    _changed: Set {},    _options:     { isNewRecord: false,       _schema: null,       _schemaDelimiter: '',       include: [Array],       includeNames: [Array],       includeMap: [Object],       includeValidated: true,       attributes: [Array],       raw: true },    isNewRecord: false,    Tags: [ [Tag] ] },  Service {    dataValues: { id: 2, name: 'Restaurant Y', Tags: [Array] },    _previousDataValues: { id: 2, name: 'Restaurant Y', Tags: [Array] },    _changed: Set {},    _options:     { isNewRecord: false,       _schema: null,       _schemaDelimiter: '',       include: [Array],       includeNames: [Array],       includeMap: [Object],       includeValidated: true,       attributes: [Array],       raw: true },    isNewRecord: false,    Tags: [ [Tag] ] } ]看起来 apollo 无法处理此数据,它不会查询后续标签实体。
查看完整描述

1 回答

?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

您应该使用instance.get方法来获取dataValues

模型实例使用属性的概念进行操作dataValues,属性存储由实例表示的实际值。

然后,您需要定义alias: 'tags'模型关联,因为 graphql 类型对象 -service具有tags字段。确保它们映射正确。

"sequelize": "^5.21.3"使用和 的工作示例"apollo-server": "^2.19.0"

model.ts

import { sequelize } from '../../db';

import { Model, DataTypes } from 'sequelize';


class Service extends Model {}

Service.init(

  {

    id: {

      primaryKey: true,

      type: DataTypes.INTEGER,

      autoIncrement: true,

      allowNull: false,

    },

    name: DataTypes.STRING,

    slug: DataTypes.STRING,

  },

  { sequelize },

);


class Tag extends Model {}

Tag.init(

  {

    id: {

      primaryKey: true,

      type: DataTypes.INTEGER,

      autoIncrement: true,

      allowNull: false,

    },

    name: DataTypes.STRING,

  },

  { sequelize },

);


Service.belongsToMany(Tag, { through: 'Service_Tag', as: 'tags' });

Tag.belongsToMany(Service, { through: 'Service_Tag', as: 'services' });


(async function test() {

  try {

    await sequelize.sync({ force: true });

    //seed

    await Service.bulkCreate(

      [

        { name: 'Restaurant X', slug: 'a', tags: [{ name: 'restaurant' }, { name: 'b' }] },

        { name: 'Restaurant Y', slug: 'b', tags: [{ name: 'c' }] },

        { name: 'Restaurant Z', slug: 'c', tags: [{ name: 'restaurant' }] },

      ],

      { include: [{ model: Tag, as: 'tags' }] },

    );

  } catch (error) {

    console.log(error);

  }

})();


export { Service, Tag };

app.ts:


import { ApolloServer, gql } from 'apollo-server';

import * as models from './model';


const typeDefs = gql`

  type Tag {

    id: ID!

    name: String!

  }


  type Service {

    id: ID!

    name: String!

    slug: String!

    tags: [Tag!]!

  }


  type Query {

    findServicesByTag(tag: String!): [Service]!

  }

`;


const resolvers = {

  Query: {

    async findServicesByTag(_, { tag }, { models }) {

      const res = await models.Service.findAll({

        where: {

          '$tags.name$': tag,

        },

        include: [

          {

            model: models.Tag,

            as: 'tags',

          },

        ],

      });

      const data = res.map((v) => v.get({ plain: true }));

      return data;

    },

  },

};


const server = new ApolloServer({

  typeDefs,

  resolvers,

  context: {

    models,

  },

});


server.listen().then(({ url }) => {

  console.log(`🚀  Server ready at ${url}`);

});

使用以下命令测试 GraphQl 查询curl:


 ⚡  curl 'http://localhost:4000/graphql' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'Origin: chrome-extension://flnheeellpciglgpaodhkhmapeljopja' --data-binary '{"query":"\nquery{\n  findServicesByTag(tag: \"restaurant\"){\n    id\n    name\n    slug\n    tags {\n      \tname\n\t\t}\n  }\n}","variables":{}}' --compressed

{"data":{"findServicesByTag":[{"id":"1","name":"Restaurant X","slug":"a","tags":[{"name":"restaurant"}]},{"id":"3","name":"Restaurant Z","slug":"c","tags":[{"name":"restaurant"}]}]}}

数据库中的数据记录:


node-sequelize-examples=# select * from "Service";

 id |     name     | slug 

----+--------------+------

  1 | Restaurant X | a

  2 | Restaurant Y | b

  3 | Restaurant Z | c

(3 rows)


node-sequelize-examples=# select * from "Tag";

 id |    name    

----+------------

  1 | restaurant

  2 | b

  3 | c

  4 | restaurant

(4 rows)

node-sequelize-examples=# select * from "Service_Tag";

 ServiceId | TagId 

-----------+-------

         1 |     1

         1 |     2

         2 |     3

         3 |     4

(4 rows)


查看完整回答
反对 回复 2023-09-28
  • 1 回答
  • 0 关注
  • 82 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信