在expressjs中使用sequelize,奇怪的是sequelize返回单条记录而不是多条记录。针对单个用户,shipping_addresses 表中插入了许多记录。我不想删除 raw:true 这是因为该结果属于 graphql 这就是为什么使用 raw:true,
shipping_addresses.belongsTo(users, { as: "userId", foreignKey: "userId"});
users.hasMany(shipping_addresses, { as: "shipping_addresses", foreignKey: "userId"});
sequelize.users.findOne({
where:{...},
include: [model:shipping_addresses, as:'shipping_addresses'],
raw:true,
nest:true
}).
这是结果
{
id:1,
username:johndeo
shipping_addresses: {
id:1
line:abc street
}
}
我在期待什么
{
id:1,
username:johndeo
shipping_addresses: [
{
id:1
line:abc street
},
{
id:2
line:another street
},
]
}
https://sequelize.org/api/v6/class/src/model.js~Model.html#instance-method-get
您不需要
raw: true
选项。相反,请致电 get({plain: true})
示例代码
async function test() {
const row = await Users.findOne({
attributes: ['id', 'username'],
where: { id: 1 },
include: [{ model: ShippingAddresses, attributes: ['id', 'line'], as: 'shipping_addresses' }],
nest: true
});
console.log(row.get({ plain: true }))
}
test()
结果
$ node test
{"pid":25056,"sql":"Executing (default): SELECT \"users\".\"id\", \"users\".\"username\", \"shipping_addresses\".\"id\" AS \"shipping_addresses.id\", \"shipping_addresses\".\"line\" AS \"shipping_addresses.line\" FROM \"users\" AS \"users\" LEFT OUTER JOIN \"shipping_addresses\" AS \"shipping_addresses\" ON \"users\".\"id\" = \"shipping_addresses\".\"user_id\" WHERE \"users\".\"id\" = 1;"}
{
id: 1,
username: 'johndeo',
shipping_addresses: [ { id: 1, line: 'abc street' }, { id: 2, line: 'another street' } ]
}
在这种情况下尽量不要使用
raw: true
和 nest: true
。我想应该有用
就我而言,我使用的是 Postgres DB,它倾向于截断关系标识符/列名称。检查调试日志,我可以看到sequelize正在生成我想要的查询。使用
raw: true
设置,我可以看到 Sequelize 也能够获得正确的“原始”结果,就像我使用 DBeaver 或 PgAdmin 查询它一样。
所以问题在于 Sequelize 如何将这些行整理成嵌套对象。通过反复试验,我发现这是两个罪魁祸首的组合:
JOIN
中,Postgres 会默默地(但 DBeaver 不会默默地)截断标识符名称,即查询的表和列别名。例如SELECT super_long_column_name AS super_long_table_name.super_long_column_name
FROM super_long_table_name;
-- # super_long_table_name.super_long_column_name will be truncated to something like super_long_table_name.supe
-- # Not sure about the exact char limit.
我们所做的解决方案或解决方法可能是在包含的模型中使用较短的别名。例如
const nestedObject = await Table1.findAll({
include: [
{
model: SuperLongTableName,
as: "super_long_table_name"
},
// ...
]
});
更改为
const nestedObject = await Table1.findAll({
include: [
{
model: SuperLongTableName,
as: "sltn"
},
// ...
]
});
然后就成功了。希望有帮助!