Node Sequelize 关联同表至两个外键字段的配置及报错解决
报错核心原因
这个问题完全是关联定义里的拼写笔误导致的,不是as别名配置逻辑的问题:
- 所有对应被关注用户(followee)的关联别名全部拼错:把
followee写成了folowee,漏掉了一个字母l - 用户表反向关联关注关系表的follower侧别名也拼错:把
follower写成了folower,同样漏了一个字母l
Sequelize解析查询时,发现follows和users之间存在2条独立关联,但你查询里写的as: 'followee'根本匹配不到你之前定义的任何别名(你实际定义的是拼写错误的folowee),无法识别对应关联,才抛出了需要指定as别名的报错。
修正方案
- 先把所有关联定义的拼写错误修正,保证查询用的别名和定义的别名完全一致:
// 关注人侧关联 this.follows.belongsTo(this.users, { as: 'follower', foreignKey: 'follower_id' }); this.users.hasMany(this.follows, { as: 'follower_follows', foreignKey: 'follower_id' }); // 被关注人侧关联 this.follows.belongsTo(this.users, { as: 'followee', foreignKey: 'followee_id' }); this.users.hasMany(this.follows, { as: 'user_followees', foreignKey: 'followee_id' });
注意:两侧的别名不需要完全一致,只要
follows模型上两个belongsTo的别名,和你查询时include传入的as完全对应即可。反向的hasMany别名是给从用户表反查关注关系场景用的,不影响当前从关注表查询用户信息的逻辑。
- 优化查询逻辑:没必要把follower_id的过滤条件放在include的关联配置里,直接在关注表的顶层where条件过滤即可,减少不必要的关联表过滤开销:
async function getFollowByFollower(follower_id) { let follows = model.follows; let users = model.users; let follow = await follows.findAll({ where: { follower_id: follower_id }, include: [ { model: users, as: 'follower', required: true }, { model: users, as: 'followee', required: true } ] }).catch(function(err) { console.log('followsDAO.js getFollowByFollower error: ' + err); }); return follow; };
注意事项
因为两个关联都设置了required: true,Sequelize会生成内连接SQL。如果存在无效的关注记录(比如对应的用户被删除,follower_id或followee_id在用户表查不到),这类记录会直接被过滤。如果需要保留所有关注关系,仅匹配存在的用户信息,把对应关联的required值改成false即可。
内容的提问来源于stack exchange,提问作者Zhang Zhan
相关产品推荐
相关产品推荐

