[英]Sequelize bulkCreate returns generated IDs or not with MySQL?
當我閱讀Sequelize 文檔時,它讓我認為無法從對bulkCreate
的調用中返回生成的 ID。 甚至returning
選項參數也說它是僅 Postgres 的功能。 這也在這個 Sequelize 問題中被引用。
但是我使用 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 會起作用嗎? 文檔的這部分是錯誤的還是措辭不當?
成功處理程序會傳遞一個實例數組,但請注意,這些實例可能無法完全代表 DB 中行的狀態。 這是因為 MySQL 和 SQLite 不容易以可以映射到多個記錄的方式獲取自動生成的 ID 和其他默認值。 要獲取新創建的值的實例,您需要再次查詢它們。
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。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.