Sequelize分组查询报homeGoals字段不存在错误解决方法
问题修复方案
错误原因
报错核心来自两个问题:
- 查询字段直接引用了数据表不存在的
team列,实际需要将主场球队字段homeTeam重命名为team返回,才能匹配预期结果结构。 - 模型配置了
underscored: true参数,该配置默认会将驼峰命名的模型属性自动映射为下划线(蛇形)命名的数据库列:- 模型属性
homeTeam对应实际列名home_team - 模型属性
homeGoals对应实际列名home_goals
而sequelize.col()方法接收的是数据库原生列名,直接传入驼峰格式的属性名会生成错误SQL,触发列找不到的报错。
- 模型属性
修复方式
方式1:直接调整查询代码(无需修改模型定义)
将查询中引用的列名替换为实际的下划线列名,同时将home_team起别名为team,修正分组配置:
public async getHomeGoals(): Promise<ILBoard> { const leaderboard = await this.matchModel.findAll({ attributes: [ // 将主场球队列重命名为team,引用实际存在的home_team列 [sequelize.col('home_team'), 'team'], // 聚合主场进球数,引用实际存在的home_goals列 [sequelize.fn('SUM', sequelize.col('home_goals')), 'goals'], ], // 按主场球队列分组 group: ['home_team'], raw: true, }); return leaderboard as unknown as ILBoard; }
方式2:修改模型定义固定列名映射(推荐,避免后续列名混乱)
如果希望数据库直接使用驼峰列名、和模型定义的属性名保持一致,可以在每个字段中显式指定field参数,覆盖underscored的自动转换逻辑:
MatchModel.init({ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false, }, homeTeam: { type: DataTypes.STRING, allowNull: false, field: 'homeTeam' }, homeGoals: { type: DataTypes.INTEGER, allowNull: false, field: 'homeGoals' }, awayTeam: { type: DataTypes.STRING, allowNull: false, field: 'awayTeam' }, awayGoals: { type: DataTypes.INTEGER, allowNull: false, field: 'awayGoals' }, }, { underscored: true, sequelize: db, modelName: 'matches', timestamps: false, });
模型修改完成后,调整查询代码的字段引用即可:
public async getHomeGoals(): Promise<ILBoard> { const leaderboard = await this.matchModel.findAll({ attributes: [ [sequelize.col('homeTeam'), 'team'], [sequelize.fn('SUM', sequelize.col('homeGoals')), 'goals'], ], group: ['homeTeam'], raw: true, }); return leaderboard as unknown as ILBoard; }
结果验证
执行修复后的代码,将得到符合预期的统计结果:
| team | goals |
|---|---|
| Arsenal | 4 |
| Everton | 2 |
内容的提问来源于stack exchange,提问作者Kelson Batista
相关产品推荐
相关产品推荐

