繁体   English   中英

Sequelize Mysql - 无法插入具有一对多关系的 model

[英]Sequelize Mysql - Unable to Insert model with one to many relationship

Design Overview:我有一个具有发票创建和库存管理功能的应用程序。 让我们首先了解具有以下两个实体的数据库设计:

  1. 发票
  2. 项目

现在,我在这两个实体之间建立了 M:N 关系,因为一张发票可以包含多个项目,并且一个项目可以包含在许多这样的发票中。

所以,我创建了第三个表,我们称之为连接表来关联这些实体,如下图所示,

数据库设计img

Problem Statemet:我无法使用 include 属性在子表 (invoice_items)中插入 model。 查看下面的代码以了解这里发生了什么问题?

3 Model 类如下:

一、发票:

Note:提供较少的属性以使其简短。

 module.exports = (sequelize, DataTypes) => { const Invoice = sequelize.define('Invoice', { invoiceId: { type: DataTypes.INTEGER.UNSIGNED, allowNull: false, autoIncrement: true, primaryKey: true }, invoiceNumber: { type: DataTypes.INTEGER(6).UNSIGNED.ZEROFILL, allowNull: false, unique: true }, invoiceTotal: { type: DataTypes.DECIMAL(9,2), allowNull: false, defaultValue: 0.00 }, paymentTotal: { type: DataTypes.DECIMAL(9,2), allowNull: false, defaultValue: 0.00 }, invoiceDate: { type: DataTypes.DATEONLY, defaultValue: DataTypes.NOW, allowNull: false } }, { underscored: true }); Invoice.associate = function (model) { Invoice.belongsTo(model.Customer, { as: 'customer', foreignKey: { name: "cust_id", allowNull: false } }); // association with 3rd table Invoice.hasMany(model.InvoiceItem, { as: 'invoice_item', constraints: true, onDelete: 'NO ACTION', foreignKey: { name: "invoice_id", allowNull: false } }); }; return Invoice; }

2.项目:

Note:提供较少的属性以使其简短。

 module.exports = (sequelize, DataTypes) => { const Item = sequelize.define('Item', { itemId: { type: DataTypes.INTEGER.UNSIGNED, allowNull: false, autoIncrement: true, primaryKey: true }, itemName: { type: DataTypes.TEXT, allowNull: false, defaultValue: '' }, // this is a opening stock quantityInStock: { type: DataTypes.INTEGER.UNSIGNED, allowNull: false, defaultValue: 0, }, unitPrice: { type: DataTypes.DECIMAL(9,2), allowNull: false, defaultValue: 0.00 } }, { underscored: true }); Item.associate = function (model) { // association with 3rd table Item.hasMany(model.InvoiceItem, { as: 'invoice_item', // alias name of a model constraints: true, onDelete: 'NO ACTION', foreignKey: { name: "item_id", allowNull: false } }); }; return Item; }

3.发票项目:

Note:提供较少的属性以使其简短。

 module.exports = (sequelize, DataTypes) => { const InvoiceItem = sequelize.define('InvoiceItem', { invoiceItemId: { type: DataTypes.INTEGER.UNSIGNED, allowNull: false, autoIncrement: true, primaryKey: true }, quantity: { type: DataTypes.INTEGER.UNSIGNED, allowNull: false, defaultValue: 0, }, rate: { type: DataTypes.DECIMAL(9,2), allowNull: false, defaultValue: 0.00 } }, { underscored: true }); InvoiceItem.associate = function(model) { InvoiceItem.belongsTo(model.Invoice, { as: 'invoice', foreignKey: { name: "invoice_id", allowNull: false } }); InvoiceItem.belongsTo(model.Item, { as: 'item', foreignKey: { name: "item_id", allowNull: false } }); } return InvoiceItem; }

现在,我正在使用下面的代码创建一个包含项目列表的发票。 但是,这并不是在连接表 ( invoice_items ) 中插入子记录。 下面的代码有什么问题?

 invoice = await Invoice.create({ "invoiceNumber": req.body.invoiceNumber, "invoiceDate": req.body.invoiceDate, "invoiceTotal": req.body.invoiceTotal, "paymentTotal": req.body.paymentTotal, "cust_id": req.body.customer.custId, invoice_items: [{ item_id: 1, quantity: 2, rate: 300 }] }, { include: [{ association: InvoiceItem, as: 'invoice_item' }] });

在尝试了这么多变化之后,我了解到我的 model 类的关联存在问题。 并且,下面是将InvoiceItem model 类关联为 M:N(多对多)关系的方式。 我现在可以更新连接表 (invoice_items),方法是为我们在系统中创建的每张发票插入记录,其中包含项目。

 Invoice.associate = function (model) { // association in Invoice model class Invoice.belongsToMany(model.Item, { through: 'InvoiceItem', constraints: true, onDelete: 'NO ACTION', foreignKey: { name: "invoice_id", // foreign key column name in a table invoice_items table allowNull: false } }); };

 Item.associate = function (model) { // association in Item model class Item.belongsToMany(model.Invoice, { through: 'InvoiceItem', constraints: true, onDelete: 'NO ACTION', foreignKey: { name: "item_id", // foreign key column name in a table invoice_items allowNull: false } }); };

创建包含项目的发票:

Note:将 itemId (1) 作为参数传递到 addItems() 方法中。 如果您在一张发票中有多个项目,那么您可以在此处添加forEach循环以遍历每个项目,并分别传递销售给客户的项目的itemIdquantityrate

 // first create the invoice invoice = await Invoice.create(invoice); // Next, add record in the join table await invoice.addItems([1], { through: { quantity: item.quantity, rate: item.rate } });

具有一个测试结果的数据库表:

1. 发票表:

发票表

2. Invoice_items 表(连接表):

发票项目表

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM