Sequelize for GraphQL 中的 OneToMany 关联。自定义外键

Posted

技术标签:

【中文标题】Sequelize for GraphQL 中的 OneToMany 关联。自定义外键【英文标题】:OneToMany association in Sequelize for GraphQL. Custom foreignKey 【发布时间】:2021-01-24 19:03:06 【问题描述】:

我正在尝试在 Sequelize 的帮助下为 GraphQL 创建一个 Apollo 服务器。

我遵循了 Sequelize 的文档和一些教程,但我仍然有错误:

User.hasMany(models.Recipe);

Recipe.belongsTo(models.User, foreignKey: 'userId' );

但是当我在 GraphQL 中执行一个突变以在我的数据库中添加一个新配方时,我观察我的控制台并且它正在执行以下查询:

INSERT INTO "Recipe" ("id","title","ingredients","direction", "userId") VALUES (DEFAULT,$1,$2,$3) RETURNING "id","title","ingredients","direction","userId", **"UserId"**;

它在 RETURNING 中比预期多一个字段,返回什么和错误,我不知道为什么。

"message": "Doesn't exist column «UserId»",
      "locations": [
        
          "line": 2,
          "column": 3
        
      ],
      "path": [
        "createRecipe"
      ],
      "extensions": 
        "code": "INTERNAL_SERVER_ERROR",
        "exception": 
          "name": "SequelizeDatabaseError",
          "parent": 
            "length": 242,
            "name": "error",
            "severity": "ERROR",
            "code": "42703",
            "hint": "You probably want to refer column «Recipe.userId».",

我知道我可以更改外键并将其命名为大写字母 ('UserId'),这样可以解决问题,但我希望能够自定义我自己的外键。

根据要求,这些是我的迁移:

await queryInterface.createTable('Recipe', 
      id: 
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      ,
      userId: 
        type: Sequelize.INTEGER,
        allowNull: false
      ,
      title: 
        allowNull: false,
        type: Sequelize.STRING
      ,
      ingredients: 
        allowNull: false,
        type: Sequelize.STRING
      ,
      direction: 
        allowNull: false,
        type: Sequelize.STRING
      
    );

await queryInterface.createTable('User', 
      id: 
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      ,
      name: 
        allowNull: false,
        type: Sequelize.STRING
      ,
      email: 
        allowNull: false,
        type: Sequelize.STRING
      ,
      password: 
        allowNull: false,
        type: Sequelize.STRING
      
    );

这是模型/recipe.js:

module.exports = (sequelize, DataTypes) => 
  const Recipe = sequelize.define('Recipe', 
    title: 
      type: DataTypes.STRING,
      allowNull: false
    ,
    ingredients: 
      type: DataTypes.STRING,
      allowNull: false
    ,
    direction: 
      type: DataTypes.STRING,
      allowNull: false
    
  , 
    modelName: 'Recipe',
    freezeTableName: true,
    timestamps: false
  );
  Recipe.associate = function(models) 
    Recipe.belongsTo(models.User);
  ;
  return Recipe;
;

这是 schema.js:

const  gql  = require('apollo-server')

const typeDefs = gql`
    type Query 
        user(id: Int!): User
        allRecipes: [Recipe!]!
        recipe(id: Int!): Recipe
    

    type User 
        id: Int!
        name: String!
        email: String!
        recipes: [Recipe!]!
      

    type Recipe 
        id: Int!
        title: String!
        ingredients: String!
        direction: String!
        user: User!
    

    type Mutation 
        createUser(name: String!, email: String!, password: String!): User!
        createRecipe(
          userId: Int!
          title: String!
          ingredients: String!
          direction: String!
        ): Recipe!
    
`

module.exports = typeDefs

谢谢!

【问题讨论】:

显示模型定义。我想你在描述userId时没有指明字段名 @Anatoly 我已编辑以显示模型。这是导致返回 userId 和 UserId 的原因吗? 您添加了迁移,但我希望看到您用于查询配方的模型定义 @Anatoly 你是这个意思吗?谢谢! 【参考方案1】:

您也应该在hasMany 中注明foreignKey 选项:

User.hasMany(models.Recipe,  foreignKey: 'useId' )

【讨论】:

以上是关于Sequelize for GraphQL 中的 OneToMany 关联。自定义外键的主要内容,如果未能解决你的问题,请参考以下文章

GraphQl,Sequelize-CLi,模型捆绑器 - sequelize.import 不是函数

GraphQL 和 graphql-sequelize-schema-generator

GraphQL 嵌套突变 + Sequelize

用 graphql-sequelize 解决“IS A”关系

GraphQL/Sequelize:SQL 别名

是否可以使用 Graphql 和 Sequelize 进行多租户?