Почему последовательности не обновляются, когда COPY выполняется в PostgreSQL?

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

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

Ответ 1

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

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

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

Обновить значение последовательности после COPY FROM:

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

Вы пишете:

он не увеличивал идентификаторы последовательности во время КОПИРОВАНИЯ как прекрасную работу во время нормального INSERTing

Но это не так!:) Когда вы выполняете обычный 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 выше.

Ответ 2

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

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

К КОПИРОВАНИЮ и оставьте последовательность из следующих действий:

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

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

Ответ 3

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

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