Почему последовательности не обновляются, когда COPY выполняется в PostgreSQL? - PullRequest
12 голосов
/ 01 февраля 2012

Я вставляю массовые записи, используя оператор COPY в PostgreSQL. Я понимаю, что идентификаторы последовательности не обновляются, и когда я пытаюсь вставить запись позже, она выдает повторяющийся идентификатор последовательности. Должен ли я вручную обновить порядковый номер, чтобы получить количество записей после выполнения COPY? Разве нет решения при выполнении COPY, просто увеличить переменную последовательности, то есть поле первичного ключа таблицы? Пожалуйста, уточните мне это. Заранее спасибо!

Например, если я вставлю 200 записей, COPY хорошо, и моя таблица показывает все записи. Когда я вручную вставляю запись позже, она говорит duplicate sequence ID error. Это очень хорошо подразумевает, что он не увеличивал идентификаторы последовательности во время копирования, так как работает нормально во время обычной вставки. Вместо указания идентификатора последовательности для установки максимального количества записей, не будет ли какого-либо механизма для обучения команды COPY увеличивать идентификаторы последовательности во время опции массового копирования?

Ответы [ 3 ]

22 голосов
/ 01 февраля 2012

Вы спрашиваете:

Стоит ли вручную обновлять порядковый номер, чтобы получить количество записей после выполнения копирования?

Да, выследует, как указано здесь :

Обновить значение последовательности после КОПИРОВАНИЯ ОТ:

| BEGIN;
| COPY distributors FROM 'input_file';
| SELECT setval('serial', max(id)) FROM distributors;
| END;

Вы пишете:

он не увеличивал идентификаторы последовательности во время копирования, так как работал нормально во время обычной вставки

Но это не так!:) Когда вы выполняете обычную INSERT, обычно вы не указываете явное значение для первичного ключа, поддерживаемого SEQUENCE.В противном случае вы столкнулись бы с теми же проблемами, что и сейчас:

postgres=> create table uh_oh (id serial not null primary key, data char(1));
NOTICE:  CREATE TABLE will create implicit sequence "uh_oh_id_seq" for serial column "uh_oh.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "uh_oh_pkey" for table "uh_oh"
CREATE TABLE
postgres=> insert into uh_oh (id, data) values (1, 'x');
INSERT 0 1
postgres=> insert into uh_oh (data) values ('a');
ERROR:  duplicate key value violates unique constraint "uh_oh_pkey"
DETAIL:  Key (id)=(1) already exists.

Ваша команда COPY, конечно, предоставляет явное значение id, как в примере INSERT выше.

6 голосов
/ 08 августа 2014

Я понимаю, что это немного устарело, но, возможно, кто-то все еще ищет ответ.

Как уже говорилось, COPY работает аналогично INSERT, поэтому для вставки в таблицу с последовательностью вы просто не упоминаете поле последовательности, и оно позаботится о вас. Для COPY это работает точно так же. Но разве для этого не требуется, чтобы ВСЕ поля в таблице присутствовали в текстовом файле? Правильный ответ НЕТ, это не так, но это поведение по умолчанию.

Чтобы скопировать и оставить последовательность, сделайте следующее:

COPY $YOURSCHEMA.$YOURTABLE(col1,col2,col3,col4) FROM '$your_input_file' DELIMITER ',' CSV HEADER;

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

3 голосов
/ 01 февраля 2012

Вы можете скопировать в сестринскую таблицу, затем insert into mytable select * from sister - это увеличит последовательность.

Если ваши загруженные данные имеют поле id, не выбирайте его для вставки: insert into mytable (col1, col2, col3) select col1, col2, col3 from sister

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...