Ruby Sequel 多行插入触发唯一约束时如何跳过对应插入行?
Dataset插入触发唯一约束时自动跳过冲突数据的实现方案
单条插入(Dataset#insert)场景
单条插入时直接链式调用insert_conflict方法,配置跳过策略即可,触发唯一约束时不会抛出异常,冲突数据直接被忽略:
# 通用写法,适配所有支持冲突处理的数据库 DB[:your_table].insert_conflict(skip: true).insert(col1: "value1", col2: "value2") # 可指定冲突的唯一约束字段,精准匹配校验规则 DB[:your_table].insert_conflict(target: :unique_col, skip: true).insert(...)
批量插入(Dataset#multi_insert)场景
multi_insert本身没有独立的冲突跳过配置项,需要搭配insert_conflict使用:
- 如果你使用Sequel 4.41.0及以上版本,且底层数据库支持批量冲突处理语法(PostgreSQL、SQLite 3.24.0+、MySQL 8.0+均支持),直接链式调用即可生效,所有触发唯一约束的行都会被自动跳过,其余数据正常写入:
DB[:your_table].insert_conflict(skip: true).multi_insert([ {col1: "value1", col2: "value2"}, {col1: "value3", col2: "value4"}, # 更多待插入数据 ])
- 如果使用低版本Sequel或者不支持对应语法的数据库,可以给
multi_insert添加slice参数分批插入,配合事务和异常捕获处理冲突,该方式性能略低,适合小批量数据场景。
补充说明
insert_conflict会自动适配底层数据库生成对应语法,比如MySQL场景会自动生成INSERT IGNORE逻辑,PostgreSQL场景会生成ON CONFLICT DO NOTHING逻辑,无需手动适配数据库差异skip: true和conflict: :do_nothing两种写法效果完全一致,可以根据个人习惯选择
内容的提问来源于stack exchange,提问作者shaan
相关产品推荐
相关产品推荐

