Javascript 如何在sequelize findAll中包含特定关联?
我已经创建了一个包含两个表的数据库,用户和点。一个用户可以有多个点,一个点存储发送该点的用户和接收该点的用户的ID。我试图查询一个按用户分组的表,该表显示了他们所有点数的总和,这在postgresql中可以查询原始数据,但在sequelize中不能 在postgresql中工作:Javascript 如何在sequelize findAll中包含特定关联?,javascript,postgresql,sequelize.js,Javascript,Postgresql,Sequelize.js,我已经创建了一个包含两个表的数据库,用户和点。一个用户可以有多个点,一个点存储发送该点的用户和接收该点的用户的ID。我试图查询一个按用户分组的表,该表显示了他们所有点数的总和,这在postgresql中可以查询原始数据,但在sequelize中不能 在postgresql中工作: User.init( { id: { type: DataTypes.INTEGER, autoIncrement: true, primaryKey: true,
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",
});
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"],
});
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";
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";
使用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",
});
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"],
});
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";
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";
尝试使用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",
});
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"],
});
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";
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";
结果错误:
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",
});
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"],
});
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";
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";
SequelizeDatabaseError:对表“users”的FROM子句项的引用无效
续集生成的SQL:
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",
});
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"],
});
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";
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";
原始查询:
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",
});
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"],
});
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";
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";
根据您的原始查询:
随时随地将“用户”更改为“用户”
在每个地方将“点”更改为“点”,如下所示:
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"],
});
请发布由代码生成的原始查询。已更新以包含生成的查询chnage
“users.name”、
到“toUser.name”、
,然后再试一次。刚刚尝试过,我收到了类似的错误:错误:对表“points”第1行的FROM子句条目的引用无效:选择“toUser”。“name”,“points”。“to_id”,SUM(“points”)。“amou…提示:也许您是想引用表别名“Point”。
更改“points.to_id”,
更改为“Point.to_id”,
谢谢,我能够使用它运行查询。您不需要指定toUser.name
属性,因为它是由续集
添加到include:['toUser']
是的,但他没有在其中定义,否则我会建议这样做