Если INSERT в таблицу не удается, то таблица UPDATE

У меня проблема выглядит так, было бы замечательно, если бы вы могли дать некоторые инструкции. Я использую PostgreSQL.

Таблица:

mytable(col1,col2,col3,count)
unique constraints on col1,col2,col3

У меня есть оператор вставки, назовите его

insert into myTable

Иногда это не удается, потому что вставка нарушает уникальные ограничения. Но я хочу поймать эту ошибку и сделать обновление, если есть уникальное_нарушение, а именно

update myTable
set count=count+1
where col1=.. and col2=.. and col3=..

Как я могу точно выразить эту семантику на языке Postgresql?

Я пробовал (кажется, синтаксически неправильно):

BEGIN;
    INSERT INTO knowledge (brand_id, brand, user_variant,score,count) 
    VALUES (%(brand_id)s, %(brand)s, %(user_variant)s,%(score)s,%(count)s);
EXCEPTION
    WHEN unique_violation THEN
    UPDATE knowledge
    SET count=count+1
    WHERE brand=%(brand)s AND user_variant=%(user_variant)s;
COMMIT;

А также python (я использую python с psycopg2)

try:
    ...
except:
    ...

что не работает, потому что попытка просто передает ошибку вставки в исключение, которое в конечном итоге вызывает ошибку:

current transaction is aborted, commands ignored until end of transaction block

Кроме того, даже sql для исключения полностью корректен.

Сейчас я пытаюсь использовать функцию pl/pgsql, но это кажется сложным.


person Hello lad    schedule 08.07.2014    source источник
comment
Вместо того, чтобы усложнять, почему бы просто не проверить, находится ли значение в таблице с помощью SELECT, если это не так, то вставить, если оно обновлено.   -  person Elias    schedule 08.07.2014
comment
@Elias: Этот подход зависит от условий гонки. Надежный upsert намного сложнее, чем кажется.   -  person mu is too short    schedule 08.07.2014
comment
stackoverflow.com/questions/1109061/ содержит массу полезной информации о том, почему у postgres нет встроенной функции upsert.   -  person Andreas    schedule 08.07.2014
comment
Поскольку вы ищете функцию plpgsql: stackoverflow.com /questions/17152860/upsert-с-транзакцией/   -  person Erwin Brandstetter    schedule 08.07.2014