主键序列不存在
primary key sequence does not exist
我有一个 postgresql 数据库,在迁移到较新版本并导入我的旧数据后,我的主键出现问题:
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint
"browser_link_pkey" Detail: Key (id)=(173) already exists.
所以我想重置我的序列,但是 运行:
select nextval('browser_link_id_seq')
也失败了:
column „browser_link_id_seq“ does not exist
SQL Status:42703
这是 SQL 用于 table 创建
CREATE TABLE browser_link (
id bigint NOT NULL,
....
);
ALTER TABLE ONLY browser_link
ADD CONSTRAINT browser_link_pkey PRIMARY KEY (id);
我尝试选择序列号,但似乎 none 存在:
postgres=# \connect historify
You are now connected to database "historify" as user "postgres".
historify=# select pg_get_serial_sequence('browser_link', 'id');
pg_get_serial_sequence
------------------------
(1 row)
我正在使用 postgresql 9.5.3。此外,在错误发生之前,id 列确实按预期递增,所以它确实有效。
现在我的两个问题:
- 为什么自动增量有效?
- 如何重置自动增量计数器?
Postgres 中的序列号是整数,默认值 由序列 提供。
在下面的片段中,table "one" 和 table "two" 完全等价:
CREATE TABLE one
( id bigserial NOT NULL PRIMARY KEY
, name varchar
);
CREATE TABLE two
( id bigint NOT NULL PRIMARY KEY
, name varchar
);
CREATE SEQUENCE "two_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
ALTER SEQUENCE "two_id_seq"
OWNED BY two.id
;
ALTER TABLE two
ALTER COLUMN id SET default nextval('two_id_seq')
;
\d one
\d two
如您所见,one
table 的 serial
语法更加紧凑(它实际上是所需 4 个语句的 shorthand 符号对于 two
table)
因此,在您的问题table 中,您可以使用 bigserial
而不是 bigint
作为数据类型重建 table,或者 "attach"通过 ALTER table ... ALTER COLUMN ...
语法将现有序列号添加到现有 id
列。
您可以通过 'setval('name', val); 将序列设置为新值,例如:
INSERT INTO two(id, name) VALUES ( 13, 'thirteen' );
select nextval('two_id_seq');
SELECT setval ('two_id_seq', (select max(id) FROM two));
select * from two;
select nextval('two_id_seq');
结果:
INSERT 0 1
nextval
---------
1
(1 row)
setval
--------
13
(1 row)
id | name
----+----------
13 | thirteen
(1 row)
nextval
---------
14
(1 row)
我有一个 postgresql 数据库,在迁移到较新版本并导入我的旧数据后,我的主键出现问题:
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint
"browser_link_pkey" Detail: Key (id)=(173) already exists.
所以我想重置我的序列,但是 运行:
select nextval('browser_link_id_seq')
也失败了:
column „browser_link_id_seq“ does not exist
SQL Status:42703
这是 SQL 用于 table 创建
CREATE TABLE browser_link (
id bigint NOT NULL,
....
);
ALTER TABLE ONLY browser_link
ADD CONSTRAINT browser_link_pkey PRIMARY KEY (id);
我尝试选择序列号,但似乎 none 存在:
postgres=# \connect historify
You are now connected to database "historify" as user "postgres".
historify=# select pg_get_serial_sequence('browser_link', 'id');
pg_get_serial_sequence
------------------------
(1 row)
我正在使用 postgresql 9.5.3。此外,在错误发生之前,id 列确实按预期递增,所以它确实有效。
现在我的两个问题:
- 为什么自动增量有效?
- 如何重置自动增量计数器?
Postgres 中的序列号是整数,默认值 由序列 提供。 在下面的片段中,table "one" 和 table "two" 完全等价:
CREATE TABLE one
( id bigserial NOT NULL PRIMARY KEY
, name varchar
);
CREATE TABLE two
( id bigint NOT NULL PRIMARY KEY
, name varchar
);
CREATE SEQUENCE "two_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
ALTER SEQUENCE "two_id_seq"
OWNED BY two.id
;
ALTER TABLE two
ALTER COLUMN id SET default nextval('two_id_seq')
;
\d one
\d two
如您所见,one
table 的 serial
语法更加紧凑(它实际上是所需 4 个语句的 shorthand 符号对于 two
table)
因此,在您的问题table 中,您可以使用 bigserial
而不是 bigint
作为数据类型重建 table,或者 "attach"通过 ALTER table ... ALTER COLUMN ...
语法将现有序列号添加到现有 id
列。
您可以通过 'setval('name', val); 将序列设置为新值,例如:
INSERT INTO two(id, name) VALUES ( 13, 'thirteen' );
select nextval('two_id_seq');
SELECT setval ('two_id_seq', (select max(id) FROM two));
select * from two;
select nextval('two_id_seq');
结果:
INSERT 0 1
nextval
---------
1
(1 row)
setval
--------
13
(1 row)
id | name
----+----------
13 | thirteen
(1 row)
nextval
---------
14
(1 row)