通过sequelize中的属性排除

时间:2017-03-11 12:42:41

标签: node.js postgresql join sequelize.js

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

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

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

虽然执行include.through.attributes = []属性不会显示在结果查询中,但是当我console.log select查询时,它仍然会选择直通表的所有属性。

是否要排除直通表?它使得groupgy在Postgres中不可能,因为它会自动选择所有列。

1 个答案:

答案 0 :(得分:0)

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

#!/usr/bin/env node

// Find all posts by users that a given user follows.
// https://stackoverflow.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;

很可能已修复。