django.db.utils.IntegrityError: 违反唯一约束条件“django_content_type_pkey”的重复键值。

30
当我运行“python manage.py syncdb”时,出现了上面的错误消息。我正在处理一个相当古老的网站,使用的是django 1.2.6和postgres DB。这次运行没有安装South,但我设法让它工作。运行“python manage.py schemamigration --initial contact_enquiries”成功运行并要求我迁移。然后我运行了“python manage.py migrate contact_enquiries”,然后出现了与上述相同的错误。它没有抱怨任何模型中的语法,这就是我困惑的原因。以下是我的模型,希望能够解决问题。
from django.db import models

class DocumentUpload(models.Model):
    name = models.CharField(max_length="200")

    document_upload = models.FileField(upload_to="uploads/documents")


    def __unicode__(self):
        return "%s" % self.name

class DocumentRequest(models.Model):
    name = models.CharField(max_length="200")

    company = models.CharField(max_length="200")

    job_title = models.CharField(max_length="200")

    email = models.EmailField(max_length="200")

    report = models.ManyToManyField(DocumentUpload)

    def __unicode__(self):
        return "%s" % self.name

如果您需要更多信息,请让我知道。

谢谢!

5个回答

77

虽然我并不百分之百确定这是问题所在,但很有可能是由于您的序列已过期。

在Postgres内执行这个操作可以解决问题吗?

SELECT setval('django_content_type_id_seq', (SELECT MAX(id) FROM django_content_type));

1
确实,面对相同的问题。可以通过 pgAdmin 实现相同的解决方案:在左窗格中浏览数据库和模式(确保在“文件”->“首选项”->“浏览器”->“节点”中可见序列)。然后选择相关表的序列:右键单击->属性。现在在定义->当前值中设置正确的值并保存。可能需要增加该值。将其设为比表中看到的最大 PK 值高 1。 - Davy
它说列“django_content_type_id_seq”不存在,但表确实存在,我不明白是哪一列?你能帮忙吗? - reindeer
也许你忘记了引号@reindeer? - Wolph

21

这通常意味着您的主键序列已失步,可能是由于错误的迁移等原因导致的。
要解决此问题:
1. 启动dbshell
python manage.py dbshell
2. 查找当前主键的最高值
select max(id) from django_content_type;
3. 将主键序列更改为从高于步骤2中找到的值开始的数字。
所以假设步骤2返回的值为290780,则将序列修改为从大于290780的数字重新开始
alter sequence django_content_type_id_seq restart with 295000;


5

这个错误意味着你的数据库序列已经过时(可能是由于之前的不正确迁移或在不同代码版本之间跳转而导致的混乱迁移顺序)。为了快速解决这个问题,你可以手动更新数据库中的值。

python manage.py dbshell

检查以下表格的当前值

SELECT last_value FROM django_migrations_id_seq;
SELECT last_value FROM django_content_type_id_seq;

然后使用以下命令更新它们(任何比上面输出值更大且合理的值)。通常,第一个命令就足够了,但如果您仍然遇到键值违反唯一约束“django_content_type_pkey”的错误,则还需要运行第二个命令(根据数据库状态可能还需要修改auth_permission_id_seq)。

ALTER SEQUENCE django_migrations_id_seq RESTART WITH {value_greater_than_last_value};
ALTER SEQUENCE django_content_type_id_seq RESTART WITH {value_greater_than_last_value};

即使在此之后,您仍然遇到错误。您可以使用以下方法:
SELECT last_value FROM auth_permission_id_seq;

将值增加一

ALTER SEQUENCE auth_permission_id_seq RESTART WITH {value_greater_than_last_value};

4

我收到了这个错误:

django.db.utils.IntegrityError: duplicate key value violates unique constraint 
    "blahmodule_blahthing_blahstuff_id"
DETAIL:  Key (blahstuff_id)=(1) already exists.

可能的解决方案:

  • 尝试将blahthing中的blahstuff关系从OneToOneField字段迁移到ForeignKey

我使用的解释:

我正在使用Django RestFramework,通过ListCreateAPIViewModelSerializer进行连接。由于某种原因,OneToOneField会将一个UNIQUE附加到一个联接表blahmodule_blahthing_blahstuff_id中(我实际上不确定它是否是一个联接表,这是一种假设),但无论发生了什么魔法,切换到带有QuerySet返回的ForeignKey后,解决了我的问题。

相关信息:

至于上述实际问题:

模式:

-- Table: public.django_content_type

-- DROP TABLE public.django_content_type;

CREATE TABLE public.django_content_type
(
    id integer NOT NULL DEFAULT nextval('django_content_type_id_seq'::regclass),
    app_label character varying(100) COLLATE pg_catalog."default" NOT NULL,
    model character varying(100) COLLATE pg_catalog."default" NOT NULL,
    CONSTRAINT django_content_type_pkey PRIMARY KEY (id),
    CONSTRAINT django_content_type_app_label_model_76bd3d3b_uniq UNIQUE (app_label, model)

)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;

ALTER TABLE public.django_content_type
    OWNER to YOURUSER;

示例行:

pk    app_label                model

1   "your_app"           "your_app_model"
2   "your_app"           "your_app_model"
3   "blah_module"        "blahthing"
4   "blah_module"        "blahstuff"

如果迁移失败,django_content_type_app_label_model_76bd3d3b_uniq的哈希值和主键可能会混乱。


1

从 Wolph 的启发,这是我的修复。

SELECT setval('django_migrations_id_seq', (SELECT MAX(id) FROM django_migrations));

1
我还发现,如果我除了反复运行'./manage.py migrate'什么都没做,最终它就能运行。 - Luke Dupin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接