我对 Sequelize 还很陌生,并试图学习所有可以用来格式化查询的很酷的技巧,但遇到了一些困难。
基本上我有一张“发票”表。我有另一个表“invoice_items”,其中许多发票_项目与一张发票有关系。
目前我正在尝试在 findAll 查询中包含此一对多关联,以便发票_项目嵌套在每个发票对象的数组中。
大致如下:
[
{
name: invoice1
invoiceItems: [
itemOne,
itemTwo,
]
},
{
name: invoice2
invoiceItems: [
itemOne,
itemTwo,
]
}
]
当我尝试这个查询时(基本上是从文档中获取的)
db.invoice.findAll({
where: {
userId: 'ed8fdd40-b807-4e51-b1f5-90fb5b7f6e73'
},
include: { all: true, nested: true }
}).then(result => {
console.log(result)
})
我遇到错误
c:\Users\brend\Desktop\projects\invoice-server\node_modules\sequelize\lib\model.js:1189
let associations = result.get(include.association.as);
^
TypeError: result.get is not a function
at c:\Users\brend\Desktop\projects\invoice-server\node_modules\sequelize\lib\model.js:1189:37
at Array.reduce (<anonymous>)
at c:\Users\brend\Desktop\projects\invoice-server\node_modules\sequelize\lib\model.js:1188:50
at Array.map (<anonymous>)
at Model._findSeparate (c:\Users\brend\Desktop\projects\invoice-server\node_modules\sequelize\lib\model.js:1186:39)
at invoice.findAll (c:\Users\brend\Desktop\projects\invoice-server\node_modules\sequelize\lib\model.js:1153:24)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Node.js v20.10.0
奇怪的是,当我尝试这样的操作时,查询成功,但未按预期格式化(每个关联的发票项目都有一个单独的发票对象)
db.invoice.findAll({
where: {
userId: 'ed8fdd40-b807-4e51-b1f5-90fb5b7f6e73'
},
include: "invoiceItems",
raw : true ,
nest : true
}).then(result => {
console.log(result)
})
为了帮助识别问题,我将在下面添加更完整的代码(想知道我是否将关联弄乱了):
发票型号
module.exports = (sequelize, Sequelize, DataType) => {
const Invoice = sequelize.define('invoice', {
id: {
type: DataType.UUID,
primaryKey: true
},
userId: {
type: DataType.UUID,
validate: {
allowNull: false
}
},
name: {
type: DataType.STRING(150)
}
//Additional fields left out here for simplicity
},{
underscored: true
});
Invoice.associate = models => {
Invoice.hasMany(models.invoiceItem), {
foreignKey: "invoiceId"
}
Invoice.belongsTo(models.user)
};
return Invoice
};
发票项目模型
module.exports = (sequelize, Sequelize, DataType) => {
const InvoiceItem = sequelize.define('invoiceItem', {
id: {
type: DataType.UUID,
primaryKey: true
},
invoiceId: {
type: DataType.UUID,
validate: {
allowNull: false
}
},
userId: {
type: DataType.UUID,
validate: {
allowNull: false
}
},
name: {
type: DataType.STRING(150)
}
//Additional fields left out here for simplicity
},{
underscored: true
});
InvoiceItem.associate = models => {
InvoiceItem.belongsTo(models.invoice, {
foreignKey: "invoiceId"
})
InvoiceItem.belongsTo(models.user), {
foreignKey: "userId"
}};
return InvoiceItem
};
最后是我的 index.js 文件,它将所有内容组合在一起
'use strict';
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const sequelize = require('../config/database.js')
const db = {}
db.Sequelize = Sequelize;
db.sequelize = sequelize;
fs.readdirSync(__dirname)
.filter(file => {
return (
file.indexOf('.') !== 0 &&
file !== basename &&
file.slice(-3) === '.js' &&
file.indexOf('.test.js') === -1
);
})
.forEach(file => {
const model = require(path.join(__dirname, file))(db.sequelize, db.Sequelize, db.Sequelize.DataTypes)
db[model.name] = model;
});
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
module.exports = db;
非常感谢任何想法或建议,提前致谢!
到目前为止,您的设置似乎是正确的,问题可能来自您指定的选项(嵌套:true):
db.invoice.findAll({
where: {
userId: 'ed8fdd40-b807-4e51-b1f5-90fb5b7f6e73'
},
include: { all: true, nested: true } <------ begin by removing nested: true
}).then(result => {
console.log(result)
})
在上面的代码中,首先删除:nested: true,您可以查看的其他选项是 plain: true、raw: true 等
最后,当我第一次创建新的续集实例时,我通过从查询默认值中删除 raw: true 来消除了错误。部分问题似乎是原始的:真正的急切加载工作。然后我可以使用 get() 方法将结果解包为我想要的格式。有关格式的更多详细信息可以在我的相关问题中找到,以防有人在某些时候发现它有帮助。