在PostgreSQL中,导入csv文件后,序列号不同步

时间:2019-04-02 23:57:33

标签: database postgresql auto-increment serial-number

我将现有的MSSQL数据移至了postgreSQL。

在此过程中,我导入/导出了csv文件。

然后序列号按顺序输入数据。

之后,当我将新值放入应用程序时,序列号无法正常工作。

如您所见,postgresql中的序列仍然固定为1。

我想知道为什么它不同步。

谢谢。

2 个答案:

答案 0 :(得分:0)

如果通过复制命令导入csv文件,则必须使用带有sequence函数的值将值设置为sequence: https://www.postgresql.org/docs/10/functions-sequence.html

SELECT setval('seq_name', your_last_number, true); --can use false in 3rd parameters

在那之后,您可以从应用中输入一个新值

答案 1 :(得分:0)

问题陈述

对于您来说,听起来您遇到的问题是您已执行以下操作:

  1. 导出的已经有序列号的数据
  2. 将导出内容导入Postgres数据库
  3. 试图插入其他数据,发现序列号之一:
    a)产生冲突,因为它试图插入现有序列号的副本;或
    b)成功插入了现有序列号的副本

Postgres中序列号的背景

在PostgreSQL中,serial数据类型实际上是integer列的简写,带有关联的sequence,该列控制该列的默认行为。

来自documentation

  

smallserial,serial和bigserial数据类型不是真实类型,而仅仅是创建唯一标识符列的符号方便(类似于某些其他数据库支持的AUTO_INCREMENT属性)。

您可以通过检查列的默认值(例如在psql中使用\d+)来验证该行为。 Default列应类似于:nextval('schema.id_seq'::regclass)。值得在文档中强调:

  

在大多数情况下,您还希望附加UNIQUE或PRIMARY KEY约束,以防止意外插入重复值,但这不是自动的。

作为旁注,请注意序列do not promise that values will be consecutive

解决方案

之所以可能最终出现在您描述的情况下,是因为仅当未明确提供值时才调用生成新值的序列。

当您将serial视为整数和默认值时,这变得更加有意义。 Postgres跟踪其下一个应使用的值的方式是通过序列,而仅在不显式提供值的情况下才从序列中分配新值。

解决此问题的方法是使用Postgres中的setval函数设置nextval。确切如何执行此操作有许多不同的策略,具体取决于您是否想要:

Here's an answer涉及如何将序列设置为特定值的相关问题。

一个简单的例子

以下示例显示了如何为插入/上传提供显式值使用默认值/序列,以及下一个插入将沿现有序列继续的方式。

CREATE TABLE test (id serial, sample integer);
INSERT INTO test (sample) VALUES (101); -- assigns default, next value from id_seq (1)
INSERT INTO test (id, sample) VALUES (3, 102); -- assigns explicit value (3)
INSERT INTO test (sample) VALUES (103); -- assigns default, next value from id_seq (2)