Sequelize 6.5嵌套关联查询子关系数据不全、键名截断异常
Sequelize三层嵌套关联查询最深层数据异常修复
问题表现
执行三层关联查询时,上层FarmVisitQuestionnaire、FarmVisitSection、FarmVisitQuestion返回结果均正常,仅最深层FarmVisitQuestionOption存在两类异常:
- 数据不全:数据库中对应问题下存储2条选项记录,查询结果仅返回1条
- 字段名截断:返回的选项记录所有字段键名被截断为单字符,例如
id对应键名为i、Label对应L、外键FarmVisitQuestionId对应F
查询代码如下:
let results = await FarmVisitQuestionnaire.findOne({ where: { Customer_ID, id:2 }, include: [{ model: FarmVisitSection, include: [{ model: FarmVisitQuestion, include: [{ model: FarmVisitQuestionOption, }] }] }], });
异常根因
两个异常来自同一个配置错误:FarmVisitQuestionOption相关的attributes配置传值格式错误。
Sequelize要求attributes参数必须传入字段名数组,如果误传入逗号分隔的字符串,框架解析时会把字符串按单个字符迭代拆分,将每个字符作为查询字段的别名,最终返回结果的键名就全是单字符。
同时拆分后的单字符无法和数据库表的真实字段名完全匹配,会导致关联查询时的键匹配逻辑出错,部分符合条件的记录被过滤,就出现了数据返回不全的问题。
上层关联无异常,是因为其余三个模型的attributes配置均为正确的数组格式,仅最深层模型配置存在问题。
排查路径
按优先级依次检查以下位置:
- 检查本次查询代码中
FarmVisitQuestionOption对应的include块,是否误给attributes传入了字符串格式的字段列表 - 检查
FarmVisitQuestionOption模型的定义文件,查看模型初始化的默认配置、默认scope中是否存在字符串格式的attributes配置 - 检查
FarmVisitQuestion和FarmVisitQuestionOption的关联定义(hasMany/belongsTo),是否在关联scope中写错了attributes的格式
修复方案
找到错误的字符串格式attributes配置,替换为字段名数组即可。
错误示例:
// 错误写法:attributes传入逗号分隔字符串 include: [{ model: FarmVisitQuestionOption, attributes: 'id,Label,Value,createdAt,updatedAt,FarmVisitQuestionId' }]
正确示例:
// 正确写法:attributes传入字段名数组 include: [{ model: FarmVisitQuestionOption, attributes: ['id', 'Label', 'Value', 'createdAt', 'updatedAt', 'FarmVisitQuestionId'] }]
如果是模型默认scope或关联配置中的错误,修改后重启服务即可恢复,修复后查询会返回全部2条选项记录,字段名也会恢复为预期的完整格式。
内容的提问来源于stack exchange,提问作者vivian2019
相关产品推荐
相关产品推荐

