嗨,我有一个问题,我知道这是多次发布,但我没有找到我的问题的答案.问题是我有一个表和一列"id"我希望它是正常的唯一数字.这种类型的列是串行的,每个插入后的下一个值是从一个序列中提交的,所以一切似乎都可以,但它仍然有时显示此错误.我不知道为什么?在文档中它是写的顺序是傻瓜教授,并始终有效.如果我向该列添加UNIQUE约束,那么它会是什么?我曾多次在Postres工作,但这个错误第一次出现在我面前.我做的一切正常,我之前从未遇到过这个问题.你能帮我找到可以在将来用于所有将要创建的表的答案吗?让我们说我们有这样的容易:
CREATE TABLE comments
(
id serial NOT NULL,
some_column text NOT NULL,
CONSTRAINT id_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE interesting.comments OWNER TO postgres;
Run Code Online (Sandbox Code Playgroud)
如果我添加:
ALTER TABLE comments ADD CONSTRAINT id_id_key UNIQUE(id)
Run Code Online (Sandbox Code Playgroud)
是否应该或是否还有其他事情要做?
ada*_*amo 63
本文解释了您的序列可能不同步,您必须手动将其重新同步.
如果URL更改,则摘自文章:
如果在尝试将数据插入PostgreSQL数据库时收到此消息:
Run Code Online (Sandbox Code Playgroud)ERROR: duplicate key violates unique constraint这可能意味着您正在使用的表中的主键序列以某种方式变得不同步,可能是因为大量导入过程(或沿着这些行的某些内容).称之为"设计错误",但似乎必须在从转储文件恢复后手动重置主键索引.无论如何,要查看您的值是否不同步,请运行以下两个命令:
Run Code Online (Sandbox Code Playgroud)SELECT MAX(the_primary_key) FROM the_table; SELECT nextval('the_primary_key_sequence');如果第一个值高于第二个值,则序列不同步.备份PG数据库(以防万一),然后运行thisL
Run Code Online (Sandbox Code Playgroud)SELECT setval('the_primary_key_sequence', (SELECT MAX(the_primary_key) FROM the_table)+1);这会将序列设置为下一个可用值,该值高于序列中任何现有的主键.
Sal*_*man 29
将 替换
table_name为您的实际表名称。
SELECT MAX(id) FROM table_name;
Run Code Online (Sandbox Code Playgroud)
SELECT nextVal('"table_name_id_seq"');
Run Code Online (Sandbox Code Playgroud)
SELECT setval('"table_name_id_seq"', (SELECT MAX(id) FROM table_name)+1);
Run Code Online (Sandbox Code Playgroud)
Som*_*ing 15
我也遇到了这个问题,@adamo 提出的解决方案基本上是正确的解决方案。然而,我不得不在细节上投入大量时间,这就是为什么我现在写一个新的答案,以便为其他人节省这个时间。
我的情况如下:有一个使用应用程序填充数据的表格。现在必须通过 SQL 手动插入一个新条目。之后序列不同步,无法通过应用程序插入更多记录。
正如@adamo 的回答中所述,必须手动同步序列。为此,需要序列的名称。对于 Postgres,可以使用命令来确定序列的名称PG_GET_SERIAL_SEQUENCE。大多数示例使用小写的表名。在我的例子中,这些表是由 ORM 中间件(如 Hibernate 或 Entity Framework Core 等)创建的,它们的名称都以大写字母开头。
在 2004 年的一封电子邮件(链接)中,我得到了正确的提示。
(让我们假设所有示例,即Foo表的名称和Foo_id相关列。)
获取序列名称的命令:
SELECT PG_GET_SERIAL_SEQUENCE('"Foo"', 'Foo_id');
Run Code Online (Sandbox Code Playgroud)
所以,表名必须用双引号括起来,用单引号括起来。
SELECT CURRVAL(PG_GET_SERIAL_SEQUENCE('"Foo"', 'Foo_id')) AS "Current Value", MAX("Foo_id") AS "Max Value" FROM "Foo";
Run Code Online (Sandbox Code Playgroud)
当Current Value小于 时Max Value,您的序列不同步。
SELECT SETVAL((SELECT PG_GET_SERIAL_SEQUENCE('"Foo"', 'Foo_id')), (SELECT (MAX("Foo_id") + 1) FROM "Foo"), FALSE);
Run Code Online (Sandbox Code Playgroud)
参考 - https://www.calazan.com/how-to-reset-the-primary-key-sequence-in-postgresql-with-django/
我有同样的问题尝试这个:
python manage.py sqlsequencereset table_name
例如:
python manage.py sqlsequencereset auth
Run Code Online (Sandbox Code Playgroud)
您需要在生产设置中运行它(如果有)并且您需要安装 Postgres 才能在服务器上运行它
对于未来的搜索,请使用 ON CONFLICT DO NOTHING。
主键已经在保护您免于插入重复值,正如您在收到该错误时所遇到的那样。为此,无需添加另一个唯一约束。
“重复键”错误告诉您工作尚未完成,因为它会产生重复键,而不是它发现已经提交到表中的重复键。
来自http://www.postgresql.org/docs/current/interactive/datatype.html
注意:在 PostgreSQL 7.3 之前,序列号隐含 UNIQUE。这不再是自动的。如果您希望序列列处于唯一约束或主键中,则现在必须指定它,与任何其他数据类型相同。