通过sequelize中的属性排除

Posted

技术标签:

【中文标题】通过sequelize中的属性排除【英文标题】:exclude through attributes in sequelize 【发布时间】:2017-08-01 19:11:18 【问题描述】:

我有 2 张表帖子和标签。我正在使用 Tag 来获取与之关联的所有帖子。

models.Tag.findAll(
attributes: ['tagName'],
include: [
 model: models.Post
  attributes: ['content']
  through: 
   attributes: []
  
 
]
)

问题是它选择了查询中的所有直通表属性。

虽然做include.through.attributes = []的属性没有出现在结果查询中,但是当我console.logselect查询时,它仍然选择了通过表的所有属性。

有排除直通表吗?它使 groupBy 在 Postgres 中变得不可能,因为它会自动选择所有列。

【问题讨论】:

github上有一张关于这个问题的ticket,据我所知,你已经评论过了,所以我认为这个问题的解决方案将首先出现;) 【参考方案1】:

我不会在sequelize@6.5.1 sqlite3@5.0.2 上复制:

#!/usr/bin/env node

// Find all posts by users that a given user follows.
// https://***.com/questions/42632943/sequelize-multiple-where-clause

const assert = require('assert');
const path = require('path');

const  Sequelize, DataTypes  = require('sequelize');

const sequelize = new Sequelize(
  dialect: 'sqlite',
  storage: 'tmp.' + path.basename(__filename) + '.sqlite',
);

(async () => 

// Create the tables.
const User = sequelize.define('User', 
  name:  type: DataTypes.STRING ,
);
const Post = sequelize.define('Post', 
  body:  type: DataTypes.STRING ,
);
User.belongsToMany(User, through: 'UserFollowUser', as: 'Follows');
User.hasMany(Post);
Post.belongsTo(User);
await sequelize.sync(force: true);

// Create data.
const users = await User.bulkCreate([
  name: 'user0',
  name: 'user1',
  name: 'user2',
  name: 'user3',
])

const posts = await Post.bulkCreate([
  body: 'body00', UserId: users[0].id,
  body: 'body01', UserId: users[0].id,
  body: 'body10', UserId: users[1].id,
  body: 'body11', UserId: users[1].id,
  body: 'body20', UserId: users[2].id,
  body: 'body21', UserId: users[2].id,
  body: 'body30', UserId: users[3].id,
  body: 'body31', UserId: users[3].id,
])

await users[0].addFollows([users[1], users[2]])

const user0Follows = await User.findByPk(users[0].id, 
  attributes: [
    [Sequelize.fn('COUNT', Sequelize.col('Follows.Posts.id')), 'count']
  ],
  include: [
    
      model: User,
      as: 'Follows',
      attributes: [],
      //through:  attributes: [] ,
      include: [
        
          model: Post,
          attributes: [],
        
      ],
    ,
  ],
)
assert.strictEqual(user0Follows.dataValues.count, 4);

await sequelize.close();
)();

美化后生成的 SELECT 是:

SELECT
  `User`.`id`,
  COUNT(`Follows->Posts`.`id`) AS `count`
FROM
  `Users` AS `User`
  LEFT OUTER JOIN `UserFollowUser` AS `Follows->UserFollowUser` ON `User`.`id` = `Follows->UserFollowUser`.`UserId`
  LEFT OUTER JOIN `Users` AS `Follows` ON `Follows`.`id` = `Follows->UserFollowUser`.`FollowId`
  LEFT OUTER JOIN `Posts` AS `Follows->Posts` ON `Follows`.`id` = `Follows->Posts`.`UserId`
WHERE
  `User`.`id` = 1;

如果我删除 through: attributes: [] , 则出现 through 属性,因此该语句正在按预期执行操作:

SELECT
  `User`.`id`,
  COUNT(`Follows->Posts`.`id`) AS `count`,
  `Follows->UserFollowUser`.`createdAt` AS `Follows.UserFollowUser.createdAt`,
  `Follows->UserFollowUser`.`updatedAt` AS `Follows.UserFollowUser.updatedAt`,
  `Follows->UserFollowUser`.`UserId` AS `Follows.UserFollowUser.UserId`,
  `Follows->UserFollowUser`.`FollowId` AS `Follows.UserFollowUser.FollowId`
FROM
  `Users` AS `User`
  LEFT OUTER JOIN `UserFollowUser` AS `Follows->UserFollowUser` ON `User`.`id` = `Follows->UserFollowUser`.`UserId`
  LEFT OUTER JOIN `Users` AS `Follows` ON `Follows`.`id` = `Follows->UserFollowUser`.`FollowId`
  LEFT OUTER JOIN `Posts` AS `Follows->Posts` ON `Follows`.`id` = `Follows->Posts`.`UserId`
WHERE
  `User`.`id` = 1;

这很可能已修复。

【讨论】:

以上是关于通过sequelize中的属性排除的主要内容,如果未能解决你的问题,请参考以下文章

node开发

建立Model

如何从sequelize中的实例中排除关联属于多?

sequelize.query() 两次返回相同的结果

在 Sequelize 中限制延迟加载的关联

sequelize 是不是可以通过关联表中的属性过滤查询?