2016-11-13 2 views
3

У меня есть процесс, который запускается каждые 5 минут и пытается вставить партию статей в таблицу. Статьи взяты из веб-лома, поэтому есть случаи, когда я пытаюсь вставить пакет, содержащий статьи, которые уже были сохранены в БД.Игнорировать ошибку в пакетной вставке Postgresql

Мой первичный ключ uuid - хеш MD5 названия статьи.

Проверка того, существует ли статья в db для фильтрации партии, является неэффективной.

Это уровень уровня DB в Postgresql, чтобы игнорировать попытки вставки дубликата uuid без возврата ошибки?

ответ

2

Решение

Вы можете вставить с помощью предложения 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) 

Отличия от ON CONFILCT

Цитирования the documentation:

ON CONFLICT может быть использован для указания альтернативных мер по повышению ограничения уникальности или ошибки нарушения исключения ограничений.

The action can beDO NOTHING или DO UPDATE. Второй подход часто упоминается как Upsert - портманте Вставки и обновления.

Технически WHERE NOT EXISTS эквивалентен ON CONFILCT DO NOTHING. Посмотрите планы запросов на более глубокое погружение.

+0

это то же самое, что делать 'ON CONFLICT DOHING','? –

+0

@AvraamMavridis Обновлен мой ответ –

Смежные вопросы