Node.js使用GraphQL查询Sequelize关联模型返回null如何解决
问题原因
关联字段返回null是两个核心原因导致的:
- Sequelize 默认不会自动加载关联模型的数据,你查询
School时没有主动指定加载关联的Grade数据,返回的School实例里自然没有grades字段值 - GraphQL只会返回你Resolver中明确提供的数据,不会自动处理关联字段的查询逻辑
前置检查
首先确认你的Grade模型中已经正确定义了反向关联,未添加的话需要补全:
// grade.js 模型中加入这段关联定义 Grade.associate = function (models) { Grade.belongsTo(models.School, { foreignKey: "school_id" }); };
解决方案1:查询时主动加载关联模型
直接在查询学校/年级的方法中加入include参数指定要关联加载的模型,修改后的resolvers.js代码如下:
const Query = { getSchoolDetails: async () => { try { // 加入include指定加载关联的Grade模型 const schools = await school.findAll({ include: 'grades' // 若关联时定义了as别名,此处写对应别名即可 }); return schools; } catch (err) { console.log(err); } }, getSchoolDetail: async (root, { id }) => { try { const scl = await school.findByPk(id, { include: 'grades' }); return scl; } catch (err) { console.log(err); } }, getGradeDetails: async () => { try { // 查询年级时加载关联的School const grades = await grade.findAll({ include: 'school' }); return grades; } catch (err) { console.log(err); } }, }
解决方案2:添加字段级Resolver(更推荐)
第一种方案不管客户端请求是否需要关联字段,都会执行关联查询,浪费性能。用字段级Resolver可以实现只有客户端请求了关联字段时才执行关联查询,更符合GraphQL按需查询的设计理念,修改后的resolvers.js完整代码如下:
const Query = { getSchoolDetails: async () => { try { // 不需要提前include,普通查询即可 const schools = await school.findAll(); return schools; } catch (err) { console.log(err); } }, getSchoolDetail: async (root, { id }) => { try { const scl = await school.findByPk(id); return scl; } catch (err) { console.log(err); } }, getGradeDetails: async () => { try { const grades = await grade.findAll({}); return grades; } catch (err) { console.log(err); } }, } // 新增School类型的字段级Resolver const School = { // 当请求School类型的grades字段时触发此Resolver grades: async (parent) => { // parent是当前查询到的School实例,直接调用Sequelize自动生成的关联查询方法即可 return await parent.getGrades(); // 若关联定义了as别名,方法名对应改为get[别名]即可 } } // 新增Grade类型的字段级Resolver const Grade = { // 当请求Grade类型的school字段时触发此Resolver school: async (parent) => { return await parent.getSchool(); } } // 导出时加入新增的Resolver module.exports = { Query, School, Grade }
两种方案任选其一即可解决关联字段返回null的问题。
内容的提问来源于stack exchange,提问作者Shruthi R
相关产品推荐
相关产品推荐

