如何使用Sequelize实现关联查询并嵌套返回关联数据?
解决Sequelize关联查询无法嵌套关联数据的问题
看起来你在关联配置的方向上搞反了,导致要么关联没生效,要么生成了多余的外键字段。咱们一步步来修正:
1. 先明确表结构的逻辑
你的Relation表应该是存储用户和团队关联关系的中间表,所以它本身应该包含两个外键:FK_User(关联User的id)和FK_Team(关联Team的id),再加上自身的id和State字段。
2. 修正模型定义
首先确保Relation模型里明确外键字段(手动定义更清晰,也可以让Sequelize自动管理):
let User = this.instance.define("User", { Name: { type: this.libraries.orm.STRING, allowNull: false } }); let Team = this.instance.define("Team", { Name: { type: this.libraries.orm.STRING, allowNull: false } }); let Relation = this.instance.define("Relation", { State: { type: this.libraries.orm.BOOLEAN, allowNull: false, defaultValue: 0 }, FK_User: { type: this.libraries.orm.INTEGER }, // 关联User表的id字段 FK_Team: { type: this.libraries.orm.INTEGER } // 关联Team表的id字段 });
3. 配置正确的关联关系
关键在这里:拥有外键的模型(也就是Relation)要使用belongsTo来关联目标模型,而不是hasOne。hasOne会把外键放在被关联的模型里(比如你之前的操作导致User表生成了多余字段),这不符合你的需求。
正确的关联配置应该是:
// Relation属于User,指定外键为FK_User,别名为FK_User Relation.belongsTo(User, { as: "FK_User", foreignKey: "FK_User", targetKey: "id" // 可选,默认关联目标模型的主键id }); // Relation属于Team,指定外键为FK_Team,别名为FK_Team Relation.belongsTo(Team, { as: "FK_Team", foreignKey: "FK_Team", targetKey: "id" });
这样配置后,Sequelize就会正确识别Relation表的外键与User、Team表主键的关联,同时不会在User或Team表生成多余字段。
4. 查询时获取嵌套数据
现在你就可以通过include进行关联查询,得到你期望的嵌套格式了:
Relation.findAll({ include: [ { model: User, as: "FK_User" }, { model: Team, as: "FK_Team" } ] }).then(relations => { // 返回结果就是你想要的格式:[{ id:1, State:true, FK_User: {id:2, Name:"my name"}, ... }] console.log(relations); });
为什么之前的配置不对?
- 你用
Relation.hasOne(User)时,Sequelize会认为User表应该有一个指向Relation的外键,这和你的中间表逻辑完全相反; - 后来添加的
User.belongsTo(Relation)更是把外键放到了User表,彻底偏离了设计意图。
只要把关联方向改成Relation.belongsTo(User/Team),就能正确建立关联并查询到嵌套数据啦!
内容的提问来源于stack exchange,提问作者Antoine Duval
相关产品推荐
相关产品推荐

