在postgresql中,导入csv文件后,序列号不同步
In postgresql, after importing the csv file, the serial number is not synchronized
我将现有的 MSSQL 数据移动到 postgreSQL。
我在此过程中导入/导出了 csv 文件。
且序号依次录入数据
当我在应用程序中输入新值后,序列号无法正常工作。
可以看到,postgresql中的sequence还是固定为1
我想知道为什么它不同步。
谢谢。
如果您通过复制命令导入 csv 文件,您必须将值设置为带有序列函数的序列::
https://www.postgresql.org/docs/10/functions-sequence.html
SELECT setval('seq_name', your_last_number, true); --can use false in 3rd parameters
之后,您可以从应用程序中输入一个新值
问题陈述
就您而言,您遇到的问题听起来像是您执行了以下操作:
- 已导出序列号的数据
- 将导出导入 Postgres 数据库
- 试图插入额外的数据,发现序列号是:
a) 产生冲突,因为它试图插入现有序列号的副本;或者
b) 成功插入现有序列号的副本
Postgres 连载的背景
在 PostgreSQL 中,serial
数据类型实际上是 integer
列的简写形式,关联的 sequence
控制列的默认行为。
The data types smallserial, serial and bigserial are not true types, but merely a notational convenience for creating unique identifier columns (similar to the AUTO_INCREMENT property supported by some other databases).
您可以通过检查列的默认值来验证该行为(例如,通过在 psql 中使用 \d+
)。 Default
列应类似于:nextval('schema.id_seq'::regclass)
。文档中值得强调的是:
In most cases you would also want to attach a UNIQUE or PRIMARY KEY constraint to prevent duplicate values from being inserted by accident, but this is not automatic.
作为旁注,重要的是要注意序列 do not promise that values will be consecutive.
解决方案
之所以可能会出现您所描述的情况,是因为生成新值的序列仅在未明确提供值时才被调用。
当您将 serial
s 视为整数和默认值时,这开始变得更有意义了。 Postgres 跟踪下一个应该使用哪个值的方式是通过序列,它仅在您未明确提供值时才从序列中分配新值。
解决这个问题的方法是使用 Postgres 中的 setval
函数设置 nextval
。具体如何执行此操作有许多不同的策略,具体取决于您是否想要:
- 重置所有序列号
- Example from Stack Overflow
- Another Example
- 保留所有现有序列号并从下一个值开始
- 其他一些自定义解决方案
Here's an answer到如何将序列设置为特定值的相关问题。
一个简单的例子
下面的示例显示了向 insert/upload 提供显式值如何 而不是 使用 default/sequence,以及下一个插入将如何继续沿着现有序列。
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)
我将现有的 MSSQL 数据移动到 postgreSQL。
我在此过程中导入/导出了 csv 文件。
且序号依次录入数据
当我在应用程序中输入新值后,序列号无法正常工作。
可以看到,postgresql中的sequence还是固定为1
我想知道为什么它不同步。
谢谢。
如果您通过复制命令导入 csv 文件,您必须将值设置为带有序列函数的序列:: https://www.postgresql.org/docs/10/functions-sequence.html
SELECT setval('seq_name', your_last_number, true); --can use false in 3rd parameters
之后,您可以从应用程序中输入一个新值
问题陈述
就您而言,您遇到的问题听起来像是您执行了以下操作:
- 已导出序列号的数据
- 将导出导入 Postgres 数据库
- 试图插入额外的数据,发现序列号是:
a) 产生冲突,因为它试图插入现有序列号的副本;或者
b) 成功插入现有序列号的副本
Postgres 连载的背景
在 PostgreSQL 中,serial
数据类型实际上是 integer
列的简写形式,关联的 sequence
控制列的默认行为。
The data types smallserial, serial and bigserial are not true types, but merely a notational convenience for creating unique identifier columns (similar to the AUTO_INCREMENT property supported by some other databases).
您可以通过检查列的默认值来验证该行为(例如,通过在 psql 中使用 \d+
)。 Default
列应类似于:nextval('schema.id_seq'::regclass)
。文档中值得强调的是:
In most cases you would also want to attach a UNIQUE or PRIMARY KEY constraint to prevent duplicate values from being inserted by accident, but this is not automatic.
作为旁注,重要的是要注意序列 do not promise that values will be consecutive.
解决方案
之所以可能会出现您所描述的情况,是因为生成新值的序列仅在未明确提供值时才被调用。
当您将 serial
s 视为整数和默认值时,这开始变得更有意义了。 Postgres 跟踪下一个应该使用哪个值的方式是通过序列,它仅在您未明确提供值时才从序列中分配新值。
解决这个问题的方法是使用 Postgres 中的 setval
函数设置 nextval
。具体如何执行此操作有许多不同的策略,具体取决于您是否想要:
- 重置所有序列号
- Example from Stack Overflow
- Another Example
- 保留所有现有序列号并从下一个值开始
- 其他一些自定义解决方案
Here's an answer到如何将序列设置为特定值的相关问题。
一个简单的例子
下面的示例显示了向 insert/upload 提供显式值如何 而不是 使用 default/sequence,以及下一个插入将如何继续沿着现有序列。
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)