忽略批量插入Postgresql中的错误

Avr*_*dis 7 sql postgresql node.js knex.js

我有一个每5分钟运行一次的过程,尝试将一批文章插入表中。这些文章来自网络废弃,因此在某些情况下,我试图插入包含已保存到数据库中的文章的批处理。

我的主键是uuid-文章标题的MD5哈希。

检查数据库中是否存在文章以过滤批处理是一种效率低下的工作。

在Postgresql中是一种数据库级别的方法来忽略在uuid不返回错误的情况下插入重复项的尝试吗?

Ada*_*tan 6

解决方案

您可以使用WHERE NOT EXISTS子句插入。

例如,考虑一个test以数字id为主键和文本的表name

代码

db=> CREATE TABLE test(id BIGSERIAL PRIMARY KEY, name TEXT);
CREATE TABLE

-- Insertion will work - empty table
db=> INSERT INTO test(id, name) 
     SELECT 1, 'Partner number 1' 
     WHERE NOT EXISTS (SELECT 1,2 FROM test WHERE id=1);
INSERT 0 1

-- Insertion will NOT work - duplicate id
db=> INSERT INTO test(id, name) 
     SELECT 1, 'Partner number 1' 
     WHERE NOT EXISTS (SELECT 1,2 FROM test WHERE id=1);    
INSERT 0 0

-- After two insertions, the table contains only one row
db=> SELECT * FROM test;
 id |       name
----+------------------
  1 | Partner number 1
(1 row)
Run Code Online (Sandbox Code Playgroud)

区别于 ON CONFILCT

引用文档

ON CONFLICT 可用于指定引发唯一约束或排除约束违反错误的替代操作。

操作可以是 DO NOTHING, 或DO UPDATE。第二种方法通常称为Upsert - 插入和更新的组合。

在技​​术上WHERE NOT EXISTS相当于ON CONFILCT DO NOTHING. 请参阅查询计划以进行更深入的了解。