gpt4 book ai didi

javascript - Sequelize bulkCreate 是否使用 MySQL 返回生成的 ID?

转载 作者:行者123 更新时间:2023-12-03 22:18:21 30 4
gpt4 key购买 nike

当我阅读 Sequelize docs 时,它让我认为无法从对 bulkCreate 的调用中返回生成的 ID。甚至 returning 选项参数也表示它是仅 Postgres 的功能。这也在 this Sequelize issue 中引用。
但是我用 Sequelize v5.21.3 和 MySQL 5.6.49 运行了下面的代码,它似乎工作得很好(注意 我什至没有传递 returning: true 选项。)

const MyEntity = sequelize.define(
"MyEntity",
{
name: {
type: DataTypes.STRING(255),
allowNull: false
},
},
{
tableName: "my_entity"
}
);
await MyEntity.sync();

const saved = await MyEntity.bulkCreate([
{ name: "test1" },
{ name: "test2" },
{ name: "test3" }
]);
console.log(`*** SAVED:\n ${JSON.stringify(saved, null, 2)}`);

它似乎正确返回了 id,打印了这个:
*** SAVED:
[
{
"id": 1,
"name": "test1",
"createdAt": "2020-09-29T14:04:27.127Z",
"updatedAt": "2020-09-29T14:04:27.127Z"
},
{
"id": 2,
"name": "test2",
"createdAt": "2020-09-29T14:04:27.127Z",
"updatedAt": "2020-09-29T14:04:27.127Z"
},
{
"id": 3,
"name": "test3",
"createdAt": "2020-09-29T14:04:27.127Z",
"updatedAt": "2020-09-29T14:04:27.127Z"
}
]
那么真相是什么?无论我尝试顶部插入多少条记录,我都可以相信返回 id 会起作用吗?文档的这部分是错误的还是措辞不当?

The success handler is passed an array of instances, but please notice that these may not completely represent the state of the rows in the DB. This is because MySQL and SQLite do not make it easy to obtain back automatically generated IDs and other default values in a way that can be mapped to multiple records. To obtain Instances for the newly created values, you will need to query for them again.

最佳答案

Sequelize 代码为 MariaDB 提供了一些解决方法,假设它们将按顺序创建,不返回带有插入的 ID,有一条评论说

//ONLY TRUE IF @auto_increment_increment is set to 1 !!


作为旁注,有趣的是不可配置且硬编码以递增 1 ...
./sequelize/lib/dialects/mariadb/query.js
  formatResults(data) {
let result = this.instance;

// update and upsert code....

if (this.isInsertQuery(data)) {

this.handleInsertQuery(data);

if (!this.instance) {
// handle bulkCreate AI primary key
if (this.model
&& this.model.autoIncrementAttribute
&& this.model.autoIncrementAttribute === this.model.primaryKeyAttribute
&& this.model.rawAttributes[this.model.primaryKeyAttribute]
) {
//ONLY TRUE IF @auto_increment_increment is set to 1 !!
//Doesn't work with GALERA => each node will reserve increment (x for first server, x+1 for next node ...
const startId = data[this.getInsertIdField()];
result = new Array(data.affectedRows);
const pkField = this.model.rawAttributes[this.model.primaryKeyAttribute].field;

// *** THIS SEQUENTIAllY INCREMENTS THE ID *** //
for (let i = 0; i < data.affectedRows; i++) {
result[i] = { [pkField]: startId + i };
}
return [result, data.affectedRows];
}

return [data[this.getInsertIdField()], data.affectedRows];
}
}

//... more code
此代码描述了获取上述代码所基于的表的 auto_increment 值的表。
./sequelize/lib/dialects/abstract/query-generator.js
  describeTableQuery(tableName, schema, schemaDelimiter) {
const table = this.quoteTable(
this.addSchema({
tableName,
_schema: schema,
_schemaDelimiter: schemaDelimiter
})
);

return `DESCRIBE ${table};`;
}
describeTableQuery()describeTable() 方法中调用:
/sequelize/lib/dialects/abstract/query-abstract.js

async describeTable(tableName, options) {
//... code
const sql = this.queryGenerator.describeTableQuery(tableName, schema, schemaDelimiter);
options = { ...options, type: QueryTypes.DESCRIBE };

try {
const data = await this.sequelize.query(sql, options);
// ...more code
MariaDB 方言类中有更多代码可以解决不直接从数据库返回的 ID。

关于javascript - Sequelize bulkCreate 是否使用 MySQL 返回生成的 ID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64125319/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com