postgresql重复密钥违反唯一约束

postgresql重复密钥违反唯一约束,postgresql,Postgresql,嗨,我有一个问题,我知道这是张贴了很多次,但我没有找到我的问题的答案。问题是我有一个表和一个列“id”,我希望它是唯一的数字,就像正常情况一样。这种类型的列是串行的,每次插入后的下一个值是从一个序列中提交的,所以看起来一切正常,但有时仍然显示此错误。我不知道为什么?在文档中,它被写入序列,并且总是有效的。如果我在该列中添加一个唯一的约束,它会被删除吗?我以前在Postres上工作过很多次,但这是我第一次看到这个错误。我做的每件事都很正常,我以前从来没有遇到过这个问题。您能帮我找到将来可用于所有将

嗨,我有一个问题,我知道这是张贴了很多次,但我没有找到我的问题的答案。问题是我有一个表和一个列“id”,我希望它是唯一的数字,就像正常情况一样。这种类型的列是串行的,每次插入后的下一个值是从一个序列中提交的,所以看起来一切正常,但有时仍然显示此错误。我不知道为什么?在文档中,它被写入序列,并且总是有效的。如果我在该列中添加一个唯一的约束,它会被删除吗?我以前在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;
如果我加上:

ALTER TABLE comments ADD CONSTRAINT id_id_key UNIQUE(id)
如果不够,或者有其他事情需要做吗?

来自


注:在PostgreSQL 7.3之前,序列号表示唯一。这不再是自动的。如果希望序列列处于唯一约束或主键中,则现在必须指定它,与任何其他数据类型相同

主键已经在保护您避免插入重复值,正如您在遇到该错误时所经历的那样。添加另一个唯一约束并不是实现这一点的必要条件

“duplicate key”错误告诉您,工作未完成是因为它将生成一个重复的键,而不是它发现了一个已提交到表中的重复键。

您的序列可能不同步,您必须手动将其恢复同步

文章摘录,以防URL更改:

CREATE TABLE public."Survey_symptom_binds"
(
    id integer NOT NULL DEFAULT nextval('"Survey_symptom_binds_id_seq"'::regclass),
    survey_id integer,
    "order" smallint,
    symptom_id integer,
    CONSTRAINT "Survey_symptom_binds_pkey" PRIMARY KEY (id)
)
SELECT nextval('"Survey_symptom_binds_id_seq"'::regclass),
       MAX(id) 
  FROM public."Survey_symptom_binds"; 
  
SELECT nextval('"Survey_symptom_binds_id_seq"'::regclass) less than MAX(id) !!!
SELECT setval('"Survey_symptom_binds_id_seq"', (SELECT MAX(id) FROM public."Survey_symptom_binds")+1);
如果您在尝试将数据插入PostgreSQL时收到此消息 数据库:

ERROR:  duplicate key violates unique constraint
这很可能意味着您正在处理的表中的主键序列 可能是因为一场大规模的灾难,与之合作变得不同步 导入过程(或类似的过程)。称之为“臭虫” “设计”,但似乎您必须手动重置主 从转储文件还原后的键索引。无论如何,看看 您的值不同步,请运行以下两个命令:

SELECT MAX(the_primary_key) FROM the_table;   
SELECT nextval('the_primary_key_sequence');
如果第一个值高于第二个值,则序列为 不同步。备份你的PG数据库(以防万一),然后运行thisL

SELECT setval('the_primary_key_sequence', (SELECT MAX(the_primary_key) FROM the_table)+1);
这会将序列设置为下一个更高的可用值 比序列中的任何现有主键都重要

我也有同样的问题,试试这个:
python manage.py sqlsequencereset table\u name

例如:

您需要在生产设置中运行此功能(如果有)
您需要安装Postgres才能在服务器上运行此功能

对于将来的搜索,请在冲突中使用,不要执行任何操作。

我也有类似的问题,但我通过删除我的Postgresql介绍中的所有外键来解决 我也遇到了这个问题,@adamo提出的解决方案基本上是正确的。然而,我不得不在细节上投入大量时间,这就是为什么我现在要写一个新的答案,以便为其他人节省时间

案例 我的案例如下:有一个表,使用应用程序填充了数据。现在,必须通过SQL手动插入一个新条目。在此之后,序列不同步,无法通过应用程序插入更多记录

解决方案 正如@adamo的回答中提到的,序列必须手动同步。为此,需要序列的名称。对于Postgres,序列的名称可以通过命令
PG\u GET\u SERIAL\u sequence
确定。大多数示例使用小写的表名。在我的例子中,这些表是由ORM中间件(如Hibernate或Entity Framework Core等)创建的,它们的名称都以大写字母开头

在2004年()的一封电子邮件中,我得到了正确的提示

(假设所有示例中,
Foo
是表的名称,
Foo\u id
是相关列。)

获取序列名称的命令:

SELECT PG_GET_SERIAL_SEQUENCE('"Foo"', 'Foo_id');
因此,表名必须用双引号括起来,并用单引号括起来

1.验证序列是否不同步 当
当前值
小于
最大值
时,序列不同步

2.校正
在我的例子中,卡拉特表脚本是:

CREATE TABLE public."Survey_symptom_binds"
(
    id integer NOT NULL DEFAULT nextval('"Survey_symptom_binds_id_seq"'::regclass),
    survey_id integer,
    "order" smallint,
    symptom_id integer,
    CONSTRAINT "Survey_symptom_binds_pkey" PRIMARY KEY (id)
)
SELECT nextval('"Survey_symptom_binds_id_seq"'::regclass),
       MAX(id) 
  FROM public."Survey_symptom_binds"; 
  
SELECT nextval('"Survey_symptom_binds_id_seq"'::regclass) less than MAX(id) !!!
SELECT setval('"Survey_symptom_binds_id_seq"', (SELECT MAX(id) FROM public."Survey_symptom_binds")+1);
所以:

CREATE TABLE public."Survey_symptom_binds"
(
    id integer NOT NULL DEFAULT nextval('"Survey_symptom_binds_id_seq"'::regclass),
    survey_id integer,
    "order" smallint,
    symptom_id integer,
    CONSTRAINT "Survey_symptom_binds_pkey" PRIMARY KEY (id)
)
SELECT nextval('"Survey_symptom_binds_id_seq"'::regclass),
       MAX(id) 
  FROM public."Survey_symptom_binds"; 
  
SELECT nextval('"Survey_symptom_binds_id_seq"'::regclass) less than MAX(id) !!!
SELECT setval('"Survey_symptom_binds_id_seq"', (SELECT MAX(id) FROM public."Survey_symptom_binds")+1);
尝试解决问题:

CREATE TABLE public."Survey_symptom_binds"
(
    id integer NOT NULL DEFAULT nextval('"Survey_symptom_binds_id_seq"'::regclass),
    survey_id integer,
    "order" smallint,
    symptom_id integer,
    CONSTRAINT "Survey_symptom_binds_pkey" PRIMARY KEY (id)
)
SELECT nextval('"Survey_symptom_binds_id_seq"'::regclass),
       MAX(id) 
  FROM public."Survey_symptom_binds"; 
  
SELECT nextval('"Survey_symptom_binds_id_seq"'::regclass) less than MAX(id) !!!
SELECT setval('"Survey_symptom_binds_id_seq"', (SELECT MAX(id) FROM public."Survey_symptom_binds")+1);

祝大家好运

如果表是由ORM中间件(如Hibernate或Entity Framework Core等)创建的,则表名以大写字母开头


我也有同样的问题。这是因为我的关系类型。我有一个与州和城市相关的表属性。所以,起初我有一个从财产到国家的关系,就像OneToOne一样,城市也是如此。我也犯了同样的错误“复制密钥违反了唯一约束”。这意味着:我只能有一个与一个州和城市相关的财产。但这没有意义,因为一个城市可以有多处房产。因此,问题在于这种关系。这种关系应该是多方面的。一个城市的多个属性显示插入数据的代码;拥有主键已经会强制一个唯一的约束,所以你不需要添加它。对我来说,我不知道如何获取“主键序列”——你可以看到,你可以使用一个名为
pg\u get\u serial\u sequence('table\u name','field\u name')的方法
使其正常工作。这确实解决了问题-任何人都知道如何使其失去同步吗?
选择setval('u primary_key_sequence',(从_表中选择MAX(the_primary_key)+1)可能不完全正确。例如,如果MAX(主键)值为9,nextval项为9,则运行
SELECT setval('the_primary_key_sequence',(从_表中选择MAX(the_primary_key))。这将自动生成下一个