Postgres «При конфликте ничего не делать» по-прежнему вставляет новую запись

#postgresql #upsert #postgresql-12

#postgresql #upsert #postgresql-12

Вопрос:

Итак, у меня есть следующий запрос PostgreSQL:

 INSERT INTO "Teams" ("name","createdAt","updatedAt") 
VALUES ('SOMETHING','2021-01-19 12:33:20.323  00:00','2021-01-19 12:33:20.323  00:00') 
ON CONFLICT DO NOTHING RETURNING *;
 

Таблица выглядит следующим образом:

 CREATE TABLE "Teams" (
    id integer NOT NULL,
    name character varying(255),
    "createdAt" timestamp with time zone NOT NULL,
    "updatedAt" timestamp with time zone NOT NULL,
    abbreviation character varying(255)
);

 

Но если я запускаю это 2 раза каждый раз, когда вставляется новая запись.

Есть идеи о том, почему он это делает, и, в основном, как предотвратить создание новых записей?

Комментарии:

1. Я удивлен, что вы не получаете сообщение об ошибке. Ваша таблица не имеет абсолютно никаких первичных или уникальных ограничений.

2. Кстати: нет никакого волшебного улучшения производительности при определении столбца varchar длиной 255 по сравнению, например, с 260 или 240.

3. Похоже, что ваше определение таблицы не включает уникальные ограничения (с которыми вы могли бы конфликтовать) или выражение по умолчанию для id столбца.

4. Почему вы думаете, что конфликт может произойти?

Ответ №1:

Вам не хватает первичного ключа или уникальных ограничений в таблице.

Если таких ограничений нет, конфликтов также не может быть, поэтому будут вставлены все строки.

Возможно, вам нужен первичный ключ id и ограничение уникальности на name :

 ALTER TABLE "Teams" ADD PRIMARY KEY (id);
ALTER TABLE "Teams" ADD UNIQUE (name);
 

Комментарии:

1. По-видимому, первичный ключ был следующей строкой в таблице создания, но unique действительно является решением для исправления повторяющихся значений