【问题标题】:exclude through attributes in sequelize通过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,据我所知,你已经评论过了,所以我认为这个问题的解决方案将首先出现;)

标签: node.js postgresql join sequelize.js


【解决方案1】:

我不会在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;

这很可能已修复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-03
    • 2019-11-14
    • 2015-10-19
    • 1970-01-01
    • 2022-11-25
    • 1970-01-01
    • 2020-12-05
    相关资源
    最近更新 更多