Sequelize嵌套include查询时无法引用ModelA表报错如何解决
报错原因
该报错是因为Sequelize处理嵌套include的内层where条件时,会将该条件放在ModelC的JOIN作用域或子查询内,默认无法访问到最外层的ModelA表字段,哪怕设置subQuery: false也会因为别名作用域限制出现引用失效。
解决方案
推荐两种可行的修改方式:
方式1:将跨层关联条件移至顶层where
把ModelC和ModelA的关联条件放到最外层的where属性中,确保可以访问到所有层级的表别名:
const model = await ModelA.findAll({ include: { model: ModelB, include: { model: ModelC // 内层不写跨层条件 }, }, where: { [Op.and]: [ sequelize.literal( '"ModelB->ModelC"."SomeColumnId" = "ModelA"."SomeColumnId"' ) ] }, subQuery: false, raw: true, });
如果执行后仍然提示别名不存在,可以先打印生成的SQL确认Sequelize自动生成的ModelC别名,或者手动给include指定别名避免歧义:
// 手动指定别名示例 include: [ {model: ModelB, as: 'b', include: [{model: ModelC, as: 'c'}]} ] // 后续literal里直接用指定的别名即可
方式2:自定义ModelC的JOIN ON条件
直接在ModelC的include配置中用on属性自定义关联规则,ON子句天然可以访问上层关联的表字段,注意要保留原来ModelB和ModelC的默认关联条件:
const model = await ModelA.findAll({ include: { model: ModelB, include: { model: ModelC, on: { [Op.and]: [ // 保留原来ModelB和ModelC的外键关联,替换为实际外键字段名 sequelize.literal('"ModelC"."modelBId" = "ModelB"."id"'), // 新增和ModelA的关联条件 sequelize.literal('"ModelC"."SomeColumnId" = "ModelA"."SomeColumnId"') ] }, // 配置为true等价于inner join,和原逻辑效果一致 required: true }, }, subQuery: false, raw: true, });
内容的提问来源于stack exchange,提问作者EZbrute
相关产品推荐
相关产品推荐

