Sequelize.js 带有sequelize联接外键的graphql

Sequelize.js 带有sequelize联接外键的graphql,sequelize.js,graphql,Sequelize.js,Graphql,我用graphql制作了简单的board api系统 我使用sequelize(版本4)连接到数据库 [schema.graphql] type Article { article_no: Int! subject: String! content: String! createdAt: String! updatedAt: String! comment: String } type Comment { article_no: Int!

我用graphql制作了简单的board api系统

我使用sequelize(版本4)连接到数据库

[schema.graphql]

type Article {
    article_no: Int!
    subject: String!
    content: String!
    createdAt: String!
    updatedAt: String!
    comment: String
}

type Comment {
    article_no: Int!
    content: String!,
    createdAt: String!
}

type Query {
    articles: [Article]!
    article(article_no: Int!): Article
    comments: [Comment]!
    comment(article_no: Int!): Comment
}

type Mutation {
    createArticle(subject: String!, content: String!, password: String!): Boolean!
    createComment(article_no: Int!, content: String!, password: String!): Boolean!
}
[resolvers.js]

import { Article, Comment } from './db';

const resolvers = {
    Query: {
        articles: async () => {
            return Article.all();
        },
        article: async(_, args) => {
            return Article.find({
                where: args.article_no,
            });
        },
        comments: async () => {
            return Comment.all();
        },
        comment: async(_, args) => {
            return Comment.find({
                where: args.article_no
            });
        }
    },
    Mutation: {
        createArticle: async (_, args) => {
            try {
                const article = await Article.create({
                    subject: args.subject,
                    content: args.content,
                    password: args.password
                });
                return true;
            } catch(e) {
                return false;
            }
        },
        createComment: async(_, args) => {
            try {
                const comment = await Comment.create({
                    article_no: args.article_no,
                    content: args.content,
                    password: args.password
                })
                return comment;
            } catch(e) {
                return false;
            }
        }
    }
}

export default resolvers;
[db.js]

const Sequelize = require('sequelize');
import config from '../config/config';

const db = new Sequelize(config.DB, config.USER, config.PASS, {
    host: 'localhost',
    dialect: 'mysql'
})

export const Article = db.define('article', {
    article_no: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    subject: {
        type: Sequelize.STRING(30),
        allowNull: false
    },
    content: {
        type: Sequelize.STRING(100),
        allowNull: false
    },
    password: {
        type: Sequelize.STRING(20),
        allowNull: false
    },
    comment: Sequelize.STRING
}, {
    freezeTableName: true,
    timestamps: true,
    underscored: true
})

export const Comment = db.define('comment', {
    content: {
        type: Sequelize.STRING(150),
        allowNull: false
    },
    password: {
        type: Sequelize.STRING(20),
        allowNull: false
    },
}, {
    freezeTableName: true,
    timestamps: true,
    underscored: true
})

Article.hasMany(Comment, {
    foreignKey: 'article_no',
    scope: {
        comment: 'comment'
    }
})
Comment.belongsTo(Article, {
    foreignKey: 'article_no',
    targetKey: 'article_no',
    allowNull: false,
    as: 'comment'
});
db.sync()
.then(console.log('[*] DB Sync Done'))
文章
评论
是1:N关系

因此,我将
hasMany
设置为
Article
,并将
belongsTo
设置为
Comment

也可以作为注释进行注释,并将其包含在文章的范围内

但是当我请求query
{article(id:1){subject,comment}}

注释返回null

我参考了文件,也遵循了这一点

但它不起作用

我的预期结果如下:

{
  "data": {
    "article": {
      "subject": "test",
      "comment": {
           "article_no":1,
           "content: "first comment",
           "created_at": "2018010101001",
           # every comment related article is here
      }
    }
  }
}
{
  "data": {
    "article": {
      "subject": "test",
      "comment": null
    }
  }
}
目前的结果如下:

{
  "data": {
    "article": {
      "subject": "test",
      "comment": {
           "article_no":1,
           "content: "first comment",
           "created_at": "2018010101001",
           # every comment related article is here
      }
    }
  }
}
{
  "data": {
    "article": {
      "subject": "test",
      "comment": null
    }
  }
}
我想显示与特定文章相关的所有评论

有什么解决办法吗


谢谢。

让您走上正轨的几条注意事项:

定义关系时,请记住,您正在调用其方法的模型就是您正在有效地向其添加属性的模型。例如,如果调用
Article.hasMany(Comment)
,这将在
Article
模型上创建
comments
属性,并将影响
Comment
模型。同样,调用
Comment.belongsTo(Article)
将在
Comment
模型上创建一个
Article
属性,而不会影响
Article
模型

请注意,即使创建了关系,如果要在查询文章时包含关联的注释(反之亦然),也必须传入相应的
include
选项。这可以直接在查询调用中完成,即

Article.findAll({ include: [Comment] })
或者可以是范围的一部分,如默认范围。范围可以设置为模型定义的一部分,也可以通过调用
addScope
在事实之后添加。例如,您可以执行以下操作:

Article.addScope('defaultScope', {
  include: [Comment],
}, { override: true })
注意:此处的
覆盖
是必要的,因为默认范围已经存在。要查询关联模型,您的查询调用或您正在使用的范围必须包括相应的
include
数组。关联也有“范围”的概念,但它不同于模型的范围。有关差异的讨论,请参见文档

最后,将
where
选项传递给
find
调用时,应确保它包含要查询的属性名称,即

Article.find({ where: { article_no: args.article_no } })

// or possibly even
Article.find({ where: args })

graphql模式和sequelize模式存在问题

让我们看看您的graphql模式

type Article { ... comment: String } 类型文章{ ... 注释:String } 你写的那篇文章和评论有1:M的关系 但是这里的注释字段是string类型,甚至不是string数组

第条的正确类型定义应为(imo):

类型文章{ ... 评论:[评论] } 现在,如果您对@Daniel Rearden的sequelize模式进行调整
在他的回答中写道,您的
文章
模型应具有
注释
属性,因此默认情况下,它将从
文章
类型的
默认解析程序
返回
注释[]
是抛出错误
语法错误:预期名称,找到[
。可能
[Comment]
是正确的方法。你说的是
如果你调用Article.hasMany(注释),这将在文章模型上创建一个comments属性,并将影响评论模型。但在我检查数据库后,没有额外的列。因此,我认为,额外的列不适用于真实的数据库,对吗?我是否应该同时设置
Article.hasMany(Comment)
Comment.belongsTo(Article)
在1:N关系中?或者只在这两者之间设置一个关系?如果我没记错的话,
hasMany
belongsTo
应该创建相应的列(在本例中是在articles表中)。是否使用一个或另一个,或者两者都使用,同样取决于您是否需要您的文章模型实例具有
comments
属性,或者您需要您的comments模型实例具有
文章
属性(或两者)。FWIW,当使用
sequelize.sync()时
您可能需要将
force
选项设置为true,以查看应用于数据库的更改()谢谢!我会尝试一下。