问题描述
在使用Sequelize进行批量插入数据时,可能会遇到如下错误:
Unhandled rejection SequelizeBulkRecordError: Validation error: xxx must be unique at /path/to/project/node_modules/sequelize/lib/model.js:2325:18 at tryCatcher (/path/to/project/node_modules/bluebird/js/release/util.js:16:23) at Promise.successAdapter
一般情况下,这个错误表示在批量插入数据时发生了重复的键约束问题。
问题原因
主要是由于使用了 bulkCreate()
方法,该方法内部使用了数据库引擎提供的优化操作(如批量插入)。数据被一次性提交到数据库服务器端进行处理。在提交数据时,可能存在多条记录具有相同的键值,比如说在一个用户的表中,有多个邮件地址都为 abc@example.com
。
这些重复的键值会被 Sequelize 框架拦截,并抛出上述的 SequelizeBulkRecordError
异常。
解决方案
1. 使用 upsert
功能
我们可以通过配置 upsert
选项来解决重复键值问题。这个选项用于指示 Sequelize,如果正在尝试插入一个已经存在的记录,则应该更新该记录而不是插入一个新记录。
Model.bulkCreate(records, { upsert: true }).then(() => { // 处理成功 }).catch(error => { // 处理失败 });
以邮件地址为例,如果在插入数据时,出现了多个 abc@example.com
的情况,则 Sequelize 会对最后一个 abc@example.com
进行更新操作,并保留其他记录。
2. 一次只插入一个记录
另一种解决方案是在记录中包含一个独特的键值,例如一个递增的主键。在这种情况下,您可以在一个循环结构中迭代地执行单个 create()
操作。
for (let record of records) { Model.create(record).then(() => { // 插入成功 }).catch(error => { // 处理失败 }); }
如果确定记录中不存在任何重复键,则通过这种方式插入将是安全的,且性能较高。
总结
以上两种方法均可用于避免 Sequelize 批量插入重复键值问题。无论您选择哪种方法,都需要小心谨慎地检查您正在插入的记录中是否存在任何重复值。当然,如果使用 upsert
功能,请确保您的目标数据表已经设置了唯一约束。
示例代码
-- -------------------- ---- ------- ----- - ---------- ------ --------- - - --------------------- ----- --------- - --- ----------------------------- ----- ---- ------- ----- -- ----------- ----- ----------------- ------ ----------------- -- - ---------- ---------- ------ --- ------ -- -- - ----- ---------------- ------ ---- --- ----- ------- - - - ----- -------- ------ ------------------- -- - ----- ------ ------ ----------------- -- - ----- ---------- ------ ----------------- -- -- ---- - ----- -------- ------ ------------------- -- -- -- ------ -- ----- ------------------------ - ------- ---- -- ------------- -- - -------------------------- - - ------- ------- ---------------- -- ------------ -- - ------------------ -------- ------ ------- ------------ --------------------------- --- -- --------- --- ---- ------ -- -------- - ----- ------------------- ------------ -- - ----------------- - - ----------- - - --- ------- ---------------- -- ------------ -- - ------------------ -------- ------ -------- ---- - - ----------- - ----- --------------------------- --- - -----
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64f38d90f6b2d6eab3cea3c8