Sequelize-从关联表返回单个列作为自定义列

pra*_*xus 0 mysql sequelize.js

我有两个模型:User和Images。用户有profile_image_id列。

当我得到用户时,include {model:Images, as:'profileImage', attributes:['filename']}我得到profileImage具有filenameas属性的对象。

Sequelize中是否有办法将“文件名”作为用户模型的属性?执行的意义

SELECT u.id, u.name, i.filename 
FROM users u 
LEFT JOIN images i ON i.id = u.profile_image_id 
WHERE u.id = 1
Run Code Online (Sandbox Code Playgroud)

现在起作用的是在用户上定义VIRTUAL属性profileImageFIlename,然后在afterFind用户模型的功能中填充它。但这似乎是很多额外的工作和不必要的数据。

除了原始查询,还有更好的方法吗?

dou*_*arp 5

简短的答案是,没有一种方法可以减少工作量。即使在示例SQL查询中,也i.filename使用为相关images表创建的别名进行引用。它有效地映射到User.images.filename,与一样有用User.profile_image_file

如果您想profile_image_id作为VIRTUAL字段存在,User那么您VIRTUAL将以正确的方式进行操作- 字段不会持久化到数据库模式,因此您需要从其他来源进行设置。在这种情况下,相关images表提供了该值,您将需要在afterfind()挂钩中进行设置。

如果您不关心它在User Instance或上,Model而只想访问结果中的值而不必遍历该对象,则可以使用以下类似的方法通过利用对该列进行别名Sequelize.literal()

User.findById(1, {
  attributes: {
    include: [[Sequelize.literal('images.filename'), 'profile_image_file']],
  },
  include: [{ model: Images, as: 'images', attributes: [] }]
})
.then((user) => {
    // There will be a user.dataValues.profile_image_file value populated
    // but not a user.profile_image_file unless you set it in afterFind()
    console.log(user.dataValues);
});
Run Code Online (Sandbox Code Playgroud)

这将导致SQL的

SELECT `user`.`id`, `user`.`name`, images.filename AS `profile_image_file`
FROM `user` AS `user` 
LEFT OUTER JOIN `images` AS `images` ON `user`.`profile_image_id` = `images`.`id` 
WHERE `user`.`id` = 1;
Run Code Online (Sandbox Code Playgroud)