【问题标题】:How to include a specific association in sequelize findAll?如何在 sequelize findAll 中包含特定关联?
【发布时间】:2019-08-20 16:05:35
【问题描述】:

我创建了一个包含两个表的数据库,用户和点。一个用户可以有很多点,一个点存储了发送它的用户和接收它的用户的 ID。我正在尝试查询按用户分组的表,显示他们所有点的总和,该表在 postgresql 中查询原始但不是在 sequelize 中。

在 postgresql 中工作:

使用 sequelize 创建模型:

User.init(
  {
    id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      primaryKey: true,
    },
    telegram_id: {
      type: DataTypes.INTEGER,
      allowNull: false,
      unique: true,
    },
    name: {
      type: DataTypes.STRING,
      allowNull: false,
    },
  },
  {
    tableName: "users",
    sequelize: sequelize, // this bit is important
  }
);

Point.init(
    {
      id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true,
      },
      amount: {
        type: DataTypes.INTEGER,
        allowNull: false,
      },
      to_id: {
        type: DataTypes.INTEGER,
        allowNull: false,
      },
      from_id: {
        type: DataTypes.INTEGER,
        allowNull: false,
      },
    },
    {
      tableName: "points",
      sequelize: sequelize, // this bit is important
    }
  );

User.hasMany(Point, {
  sourceKey: "telegram_id",
  foreignKey: "to_id",
  as: "recievedPoints", // this determines the name in `associations`!
});

User.hasMany(Point, {
  sourceKey: "telegram_id",
  foreignKey: "from_id",
  as: "sentPoints", // this determines the name in `associations`!
});

Point.belongsTo(User, {
  foreignKey: "to_id",
  targetKey: "telegram_id",
  as: "toUser",
});
Point.belongsTo(User, {
  foreignKey: "from_id",
  targetKey: "telegram_id",
  as: "fromUser",
});

尝试使用 sequelize 进行相同的查询:

  const points = await Point.findAll({
    attributes: [
      "users.name",
      "points.to_id",
      [Sequelize.fn("SUM", Sequelize.col("points.amount")), "points.amount"],
    ],
    include: ["toUser"],
    group: ["users.name", "points.to_id"],
  });

产生的错误:

SequelizeDatabaseError: 对表“users”的 FROM 子句条目的无效引用

sequelize生成的SQL:

SELECT "users"."name", "points"."to_id", SUM("points"."amount") AS "points.amount", "toUser"."id" AS "toUser.id", "toUser"."telegram_id" AS "toUser.telegram_id", "toUser"."name" AS "toUser.name", "toUser"."createdAt" AS "toUser.createdAt", "toUser"."updatedAt" AS "toUser.updatedAt" FROM "points" AS "Point" 
LEFT OUTER JOIN "users" AS "toUser" ON "Point"."to_id" = "toUser"."telegram_id" GROUP BY "users"."name", "points"."to_id";

【问题讨论】:

  • 请贴出代码生成的原始查询。
  • 已更新以包含生成的查询
  • "users.name", 更改为 "toUser.name", ,然后重试
  • 刚刚尝试过并收到类似的错误:ERROR: invalid reference to FROM-clause entry for table "points" LINE 1: SELECT "toUser"."name", "points"."to_id", SUM("points"."amou... HINT: Perhaps you meant to reference the table alias "Point".
  • "points.to_id", 更改为 "Point.to_id",

标签: javascript postgresql sequelize.js


【解决方案1】:

原始查询:

SELECT "users"."name", "points"."to_id", SUM("points"."amount") AS "points.amount", "toUser"."id" AS "toUser.id", "toUser"."telegram_id" AS "toUser.telegram_id", "toUser"."name" AS "toUser.name", "toUser"."createdAt" AS "toUser.createdAt", "toUser"."updatedAt" AS "toUser.updatedAt" 
FROM "points" AS "Point" 
LEFT OUTER JOIN "users" AS "toUser" ON "Point"."to_id" = "toUser"."telegram_id" GROUP BY "users"."name", "points"."to_id";

根据您的原始查询:

“users”更改为“toUser”在任何地方

"points" 更改为 "Point" 每个位置,如下所示:

const points = await Point.findAll({
    attributes: [
        "toUser.name",
        "Point.to_id",
        [Sequelize.fn("SUM", Sequelize.col("Point.amount")), "Point.amount"],
    ],
    include: ["toUser"],
    group: ["toUser.name", "Point.to_id"],
});

【讨论】:

  • 谢谢,我可以用这个来运行查询
  • 你不需要指定toUser.name属性,因为它是Sequelizeinclude: ['toUser']范围内添加的
  • 是的,但他没有在里面定义,否则我会建议
猜你喜欢
  • 2018-07-13
  • 2020-01-01
  • 1970-01-01
  • 2017-05-19
  • 1970-01-01
  • 2023-03-24
  • 2017-02-11
  • 1970-01-01
  • 2017-07-21
相关资源
最近更新 更多