Postgres «при конфликте ... сделать обновление» не удалось с нарушением UniqueContraint - PullRequest
0 голосов
/ 27 марта 2020

Я хочу реализовать здесь upsert. Значения в некоторых столбцах будут обновляться при каждой вставке.

Я использую -

insert into deployment.nodes values('sind','11', now(),'temp','not-active')  
on conflict on constraint nodes_pkey 
   DO UPDATE SET latest=now(), agent='na', status='active';

Таблица - -

create table if not exists deployment.nodes (
   account varchar(40), 
   hostname varchar(100),
   latest timestamptz, 
   agent varchar(50),
   status varchar(50), 
   primary key(account,hostname,agent)
);

После двух / трех вставок я получаю -

devops=# insert into deployment.nodes values('sind','11', now(),'temp','not-active')  on conflict on constraint nodes_pkey DO UPDATE SET latest=now(), agent='ne', status='active';
INSERT 0 1
devops=# insert into deployment.nodes values('sind','11', now(),'temp','not-active')  on conflict on constraint nodes_pkey DO UPDATE SET latest=now(), agent='ne', status='active';
INSERT 0 1
devops=# insert into deployment.nodes values('sind','11', now(),'temp','not-active')  on conflict on constraint nodes_pkey DO UPDATE SET latest=now(), agent='ne', status='active';
INSERT 0 1
devops=# insert into deployment.nodes values('sind','11', now(),'temp','not-active')  on conflict on constraint nodes_pkey DO UPDATE SET latest=now(), agent='ne', status='active';
ERROR:  duplicate key value violates unique constraint "nodes_pkey"
DETAIL:  Key (account, hostname, agent)=(sind, 11, ne) already exists.

Postgres Версия -

devops=# SHOW server_version;
 server_version
----------------
 10.11

Есть идеи, что происходит?

Ответы [ 2 ]

0 голосов
/ 27 марта 2020

Спасибо @Bjarni за его очистку.

Предполагается, что обновление по конфликту обновит строку, вызвавшую конфликт. В моем случае, похоже, что у самого средства разрешения конфликтов был конфликт.

Я использовал те же значения первичного ключа в своем «операторе вставки», как и в «заявлении конфликта», и это решило проблему.

insert into deployment.nodes 
values('sind','11', now(),'temp','not-active')  
on conflict on constraint nodes_pkey 
   DO UPDATE SET latest=now(), agent='temp', status='active';

Спасибо!

0 голосов
/ 27 марта 2020

Это нормальное поведение. Первая вставка вставляет с агентом темп. Вторая попытка вставки обновляет первую запись для агента ne. Третий снова вставляет temp агента в новую запись, а четвертый пытается обновить temp до agent ne, вызывая конфликт с первым.

С уважением,
Bjarni

...