Apollo,Sequelize - 简单的 `belongsTo` 关联返回 null

Posted

技术标签:

【中文标题】Apollo,Sequelize - 简单的 `belongsTo` 关联返回 null【英文标题】:Apollo, Sequelize - Simple `belongsTo` association returns null 【发布时间】:2020-12-22 16:49:38 【问题描述】:

尝试为我的 apollo graphql api 在 sequelize 中设置一个简单的关联。我有两张桌子:userrole。每个用户都有一个role_id 列,该列引用role 表中的主键。

每当我查询时:


  users
    id,
    email,
    role
      id
    
  ,

我收到以下错误:"Cannot return null for non-nullable field User.role.",

我是 sequelize/apollo 的新手,但看不到哪里出错了。

models/user.js

'use strict';

const  Model  = require('sequelize');

module.exports = (sequelize, DataTypes) => 
  class User extends Model 
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) 
      // define association here
      User.belongsTo(models.Role);
    
  ;

  User.init(
    email: DataTypes.STRING,
    password: DataTypes.STRING,
  , 
    sequelize,
    tableName: 'user',
    schema: 'auth',
    modelName: 'User',
    timestamps: false,
    underscored: true,
  );

  return User;
;

models/role.js

'use strict';

const  Model  = require('sequelize');

module.exports = (sequelize, DataTypes) => 
  class Role extends Model 
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) 
      // define association here
      Role.hasMany(models.User)
    
  ;

  Role.init(
    name: DataTypes.STRING,
    isDefault: 
      type: DataTypes.BOOLEAN,
      field: 'is_default'
    ,
  , 
    sequelize,
    tableName: 'role',
    schema: 'auth',
    modelName: 'Role',
    timestamps: false,
    underscored: true,
  );

  return Role;
;

模型在 my:models/index.js 中与以下 sn-p 相关联:

...
Object.keys(db).forEach(modelName => 
  if (db[modelName].associate) 
    db[modelName].associate(db);
  
);

// sync models - modifies the database to match every model
sequelize.sync( alter: true, match: /-apollo$/ )
...

这是我的:resolvers/user.js

module.exports = 
  Query: 
    users: async (parent, args,  models ) => 
      return await models.User.findAll( include: [model: models.Role] );
    ,
    user: async (parent,  id ,  models ) => 
      return await models.User.findByPk(id);
    ,
  ,
;

任何帮助将不胜感激!

编辑:我创建了一个新数据库并将sequelize.sync() 添加到我的models/index.js 以确保这不是由我的数据库设置中的某些错误引起的。

【问题讨论】:

【参考方案1】:

找到了解决办法。我的问题是 sequelize 自动命名关联,在我的情况下这是出乎意料的,因此我的架构与关联的实际名称不匹配,导致空值。

为了解决这个问题,我将 as: "something" 属性添加到我的关联中:

resolvers/user.js

module.exports = 
  Query: 
    users: async (parent, args,  models ) => 
      return await models.User.findAll( include: [model: models.Role, as: 'role'] );
    ,
    user: async (parent,  id ,  models ) => 
      return await models.User.findByPk(id);
    ,
  ,
;

【讨论】:

以上是关于Apollo,Sequelize - 简单的 `belongsTo` 关联返回 null的主要内容,如果未能解决你的问题,请参考以下文章

meteor apollo graphql/sequelize 缓存查询结果,避免多次相同查询

GraphQL 嵌套突变 + Sequelize

GraphQL/Sequelize:SQL 别名

仅从 sequelize junction 模型返回指定的关联模型

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

Apollo:所需的服务器响应形状?