【发布时间】:2020-04-25 07:20:33
【问题描述】:
我有一个Invoice 模型,它可以与多个LineItem 模型关联。当我调用setLineItems(lineItems, {transaction: t});(其中lineItems 是LineItem 对象的数组)时,我收到一个错误,因为Sequelize 在scnenes 后面创建了一些非常奇怪的SQL:
DatabaseError [SequelizeDatabaseError]: invalid input syntax for integer: "[object Object]"
// Stack trace cut out
{
name: 'error',
length: 108,
severity: 'ERROR',
code: '22P02',
detail: undefined,
hint: undefined,
position: '69',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'numutils.c',
line: '62',
routine: 'pg_atoi',
sql: `UPDATE "LineItems" SET "invoiceId"=$1,"updatedAt"=$2 WHERE "id" IN ('[object Object]', '[object Object]')`,
parameters: [ 8, '2020-04-25 06:56:19.482 +00:00' ]
}
我的代码/定义如下:
invoice.js:
'use strict';
module.exports = (sequelize, DataTypes) => {
const Invoice = sequelize.define('Invoice', {
// various fields, including a numeric id
}, {});
Invoice.associate = function (models) {
Invoice.hasMany(models.LineItem, { foreignKey: 'invoiceId' });
};
return Invoice;
};
lineItems.js:
'use strict';
module.exports = (sequelize, DataTypes) => {
const LineItem = sequelize.define('LineItem', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
invoiceId: {
type: DataTypes.INTEGER,
references: {
model: 'Invoices',
key: 'id'
},
},
hsnSacCode: DataTypes.STRING(30),
desc: DataTypes.STRING(1500),
qty: DataTypes.DECIMAL(10, 3),
rate: DataTypes.DECIMAL(10, 3),
amt: DataTypes.DECIMAL(16, 3)
}, {});
LineItem.associate = function (models) {
};
return LineItem;
};
Invoice 迁移:
'use strict';
const tbl = 'Invoices';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable(tbl, {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
// other fields
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Invoices');
}
};
LineItem 迁移:
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('LineItems', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
invoiceId: {
type: Sequelize.INTEGER,
references: {
model: 'Invoices',
key: 'id'
},
onUpdate: 'CASCADE',
onDelete: 'SET NULL'
},
hsnSacCode: {
type: Sequelize.STRING(30)
},
desc: {
type: Sequelize.STRING(1500)
},
qty: {
type: Sequelize.DECIMAL(10,3)
},
rate: {
type: Sequelize.DECIMAL(10,3)
},
amt: {
type: Sequelize.DECIMAL(16,3)
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('LineItems');
}
};
奇怪的是,生成的SQL竟然这么错误!!示例:
START TRANSACTION;
INSERT INTO "Invoices" ("id","invoiceNum","vendorId","corporateId","dated","currency","preTaxAmt","igstPct","sgstPct","totalAmt","tdsPaid","gstInputCreditClaimed","status","vendorStatus","type","createdAt","updatedAt") VALUES (DEFAULT,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16) RETURNING *;
SELECT "id", "invoiceId", "hsnSacCode", "desc", "qty", "rate", "amt", "createdAt", "updatedAt" FROM "LineItems" AS "LineItem" WHERE "LineItem"."invoiceId" = 8;
UPDATE "LineItems" SET "invoiceId"=$1,"updatedAt"=$2 WHERE "id" IN ('[object Object]', '[object Object]')
ROLLBACK;
这是执行的代码:
const dbInvoice = await sequelize.transaction(async (t) => {
const invoice = _.omit(input, ['lineItems']);
const { lineItems } = _.pick(input, ['lineItems']);
const dbInvoice = await Invoice.create(invoice, { transaction: t });
console.log(`lineItems:`, lineItems);
await dbInvoice.setLineItems(lineItems, {transaction: t});
return Promise.resolve(dbInvoice.dataValues);
});
在我尝试保存之前lineItems 的console.log 输出:
lineItems: [
{
hsnSacCode: 'arbit',
desc: 'Daycare for Child1, Child2',
qty: 2,
rate: '2000.00',
amt: '4000.00'
},
{
hsnSacCode: 'arbit',
desc: 'Daycare for Child1, Child2',
qty: 1,
rate: '2000.00',
amt: '2000.00'
}
]
如果我用刚刚保存的Invoice 的id 填充每个lineItem,然后正常保存它们(即不使用setLineItems(...)),它会按预期工作。
使用 PostgresQL RDBMS。
续集:[节点:12.14.1,CLI:5.5.1,ORM:5.21.3
【问题讨论】:
-
显示console.log的输出(
lineItems:, lineItems); -
@Anatoly 刚刚添加了
lineItems的console.log输出。 -
如果您在创建之前尝试将 invoiceId: dbInvoice.id 添加到每个 lineItem 会怎样?
-
@Anatoly 我在调用
setLineItems()之前添加了lineItems.forEach(li => { li.invoiceId = dbInvoice.dataValues.id; });行,结果是一样的。console.log()输出显示添加的invoiceId字段设置为正确的值。 -
还将 Sequelize 更新到版本
5.21.7(来自5.21.3),但没有任何变化。
标签: sequelize.js