我在PostgreSQL中使用COPY
语句插入批量记录。我意识到,序列ID没有得到更新,当我尝试稍后插入记录时,它会抛出重复的序列ID。我应该在执行COPY
后手动更新序列号以获取记录数量吗?执行COPY
时是否有解决方案,只需递增序列变量,即表的主键字段?请澄清一下。提前谢谢!
例如,如果我插入200条记录,COPY
表示良好,我的表格会显示所有记录。当我稍后手动插入记录时,它会显示duplicate sequence ID error
。这很好地暗示它在COPYing期间没有增加序列ID,因为在正常INSERTing期间工作正常。而不是指示序列id设置最大记录数,是否有任何机制来教育COPY
命令在批量COPYing选项期间增加序列ID?
答案 0 :(得分:22)
你问:
我应该在执行COPY后手动更新序列号以获取记录数吗?
是的,您应该documented here:
在COPY FROM后更新序列值:
| BEGIN; | COPY distributors FROM 'input_file'; | SELECT setval('serial', max(id)) FROM distributors; | END;
你写道:
它在COPYing期间没有增加序列ID,因为在正常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一样。
答案 1 :(得分:6)
我意识到这有点老了,但也许有人可能仍在寻找答案。
正如其他人所说的COPY以与INSERT类似的方式工作,因此对于插入具有序列的表,您根本就不提及序列字段,而是为您处理。对于COPY,它以同样的方式工作。但它不是COPY要求表中的所有字段都出现在文本文件中吗?正确的答案是NO,但它没有,但这是默认行为。
要复制并退出序列,请执行以下操作:
COPY $YOURSCHEMA.$YOURTABLE(col1,col2,col3,col4) FROM '$your_input_file' DELIMITER ',' CSV HEADER;
之后无需手动更新架构,它可以按预期工作,在我的测试中速度也一样快。
答案 2 :(得分:3)
您可以复制到姐妹表,然后insert into mytable select * from sister
- 这会增加序列。
如果您加载的数据具有id字段,请不要为插入选择它:insert into mytable (col1, col2, col3) select col1, col2, col3 from sister