Sequelize关联查询报Product.product_category_id未知列错误
Sequelize关联查询报错Unknown column 'Product.product_category_id'修复
问题表现
使用Sequelize开发时,框架自动生成的SELECT查询语句字段列表中额外拼接了不存在的列,触发报错:
SequelizeDatabaseError: Unknown column 'Product.product_category_id' in 'field list'
初步排查确认问题范围锁定在ProductCategory与Product两个模型的关联配置环节。
相关模型原代码
ProductCategory模型
module.exports = (sequelize, dataTypes) => { let alias = 'ProductCategory'; let cols = { id: { type: dataTypes.SMALLINT(3), notNull: true, primaryKey: true, autoIncrement: true, }, name: { type: dataTypes.STRING(60), defaultValue: null, }, }; let config = { tableName: 'product_categories', timestamps: false, underscored: true, }; const ProductCategory = sequelize.define(alias, cols, config); ProductCategory.associate = function (models) { ProductCategory.hasMany(models.Product, { foreingKey: 'category_id', as: 'ProductCategory', }); }; return ProductCategory; };
Product模型
module.exports = (sequelize, dataTypes) => { let alias = 'Product'; let cols = { id: { type: dataTypes.INTEGER, primaryKey: true, notNull: true, }, brand_id: { type: dataTypes.SMALLINT(8), defaultValue: null, }, gender: { type: dataTypes.STRING(30), defaultValue: null, }, discount_percentage: { type: dataTypes.SMALLINT(3), defaultValue: null, }, price: { type: dataTypes.DECIMAL(11, 2), defaultValue: null, }, description: { type: dataTypes.STRING(500), defaultValue: null, }, color: { type: dataTypes.STRING(30), defaultValue: null, }, category_id: { type: dataTypes.SMALLINT(3), defaultValue: null, }, }; let config = { tableName: 'products', timestamps: false, underscored: true, }; const Product = sequelize.define(alias, cols, config); Product.associate = function (models) { Product.belongsTo(models.Brand, { foreingKey: 'brand_id', as: 'Brand', }); Product.belongsTo(models.ProductCategory, { foreingKey: 'category_id', as: 'ProductCategory', }); Product.belongsToMany(models.Cart, { through: 'cart_products', foreingKey: 'product_id', otherKey: 'cart_id', timestamps: false, }); Product.belongsToMany(models.Size, { through: models.ProductSize, foreingKey: 'product_id', otherKey: 'size_id', timestamps: false, }); }; return Product; };
报错截图


问题根因
两处配置错误导致Sequelize未读取到自定义外键配置,自动按默认命名规则生成了不存在的外键字段product_category_id:
- 所有关联配置的外键属性名拼写错误:Sequelize规定自定义外键的属性名为
foreignKey,原代码中全部错写为foreingKey(漏写字母n)。Sequelize不会对未知配置属性抛错,会直接忽略该配置项,回退到默认外键命名逻辑(关联模型名转下划线拼接_id)生成查询字段。 ProductCategory侧hasMany关联的别名配置不合理:和Product侧belongsTo的别名重名,容易引发关联映射逻辑混乱。
修复步骤
- 修正
ProductCategory模型关联配置:将拼写错误的foreingKey改为foreignKey,同时调整hasMany的别名为集合语义的命名,避免和反向关联别名冲突:
ProductCategory.associate = function (models) { ProductCategory.hasMany(models.Product, { foreignKey: 'category_id', as: 'products', }); };
- 修正
Product模型中所有关联的外键属性拼写:把所有foreingKey替换为foreignKey,其余配置保留即可:
Product.associate = function (models) { Product.belongsTo(models.Brand, { foreignKey: 'brand_id', as: 'Brand', }); Product.belongsTo(models.ProductCategory, { foreignKey: 'category_id', as: 'ProductCategory', }); Product.belongsToMany(models.Cart, { through: 'cart_products', foreignKey: 'product_id', otherKey: 'cart_id', timestamps: false, }); Product.belongsToMany(models.Size, { through: models.ProductSize, foreignKey: 'product_id', otherKey: 'size_id', timestamps: false, }); };
- 后续做预加载查询时,
include配置的as参数必须和关联定义的别名完全匹配:- 查询分类并挂载下属产品时,
as传'products' - 查询产品并挂载所属分类时,
as传'ProductCategory'
- 查询分类并挂载下属产品时,
修改完成后重启服务,Sequelize会正确识别自定义的category_id外键,不会再生成不存在的product_category_id字段,报错即可解决。
内容的提问来源于stack exchange,提问作者BautistaCodes
相关产品推荐
相关产品推荐

