Node.js Sequelize ORM多对多关联配置sourceKey时触发TypeError错误求助
Cannot read properties of undefined (reading 'field')错误 我之前也碰到过一模一样的问题,这个错误本质是Sequelize在你的Hostel模型里找不到你指定的sourceKey(也就是hostel_id)对应的属性,导致读取field属性时触发了undefined错误。下面是我总结的排查和解决步骤:
1. 先检查模型字段的定义是否正确
打开你的Hostel.ts文件,确认hostel_id字段是否真的在模型里正确定义了,要注意这几点:
- 字段名的拼写和大小写完全匹配,别把
hostel_id写成hostelId或者HostelId(除非你设置了underscored: true,后面会说这个) - 如果是手动指定数据库字段名,要确保
field属性和你写的sourceKey一致
比如正确的字段定义应该是这样的:
hostel_id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, // 如果你的数据库字段名和模型属性名一致,field可以省略 // field: 'hostel_id' }
2. 确认关联代码的执行时机
很多时候这个错误是因为关联代码跑在了模型初始化完成之前!比如你在Hostel模型还没执行完init方法的时候,就调用了belongsToMany,这时候Sequelize还没加载到hostel_id这个属性,自然会报找不到的错误。
解决方法很简单:把关联代码放在模型init方法的后面,或者单独抽一个关联初始化文件,等所有模型都加载完成后再统一执行关联配置。
3. 修正多对多关联的through配置
你用了带schema的表名university.hostels_to_faculties,有时候Sequelize对这种写法的解析会有问题,建议改成对象形式明确指定schema和表名:
Hostel.belongsToMany(Faculty, { through: { model: 'hostels_to_faculties', schema: 'university' }, sourceKey: 'hostel_id', targetKey: 'faculty_id', onUpdate: 'CASCADE', onDelete: 'CASCADE' });
同时别忘了检查Faculty模型里是否存在faculty_id这个字段,别在targetKey上犯同样的错误。
4. 注意underscored配置的影响
如果你的Hostel模型设置了underscored: true,Sequelize会自动把模型中的驼峰属性名转换成下划线形式的数据库字段名。这时候要注意:sourceKey指定的是模型中的属性名,不是数据库里的字段名!
比如如果模型里定义的是hostelId,数据库字段是hostel_id,那sourceKey应该写hostelId,而不是hostel_id。
最后给个正确的示例片段
import { Model, DataTypes } from 'sequelize'; import sequelize from '../path/to/your/sequelize/config'; import Faculty from './Faculty'; class Hostel extends Model {} Hostel.init( { hostel_id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, }, // 其他字段... }, { sequelize, modelName: 'Hostel', tableName: 'hostels', schema: 'university', // 如果开启underscored,模型属性名会自动转下划线 // underscored: true, } ); // 一定要在模型init之后再执行关联 Hostel.belongsToMany(Faculty, { through: { model: 'hostels_to_faculties', schema: 'university', }, sourceKey: 'hostel_id', targetKey: 'faculty_id', onUpdate: 'CASCADE', onDelete: 'CASCADE', }); export default Hostel;
按照上面的步骤排查,应该就能解决这个问题了。
内容的提问来源于stack exchange,提问作者Sardorkhuja Tukhtakhodjaev

