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

Posted

技术标签:

【中文标题】django.db.utils.IntegrityError:重复键值违反唯一约束“django_content_type_pkey”【英文标题】:django.db.utils.IntegrityError: duplicate key value violates unique constraint "django_content_type_pkey" 【发布时间】:2013-10-08 17:35:29 【问题描述】:

遇到了一点问题,当我运行“python manage.py syncdb”时,我收到了上述错误消息,我正在一个相当旧的站点上工作。它使用 postgres DB 运行 django 1.2.6。

运行没有安装南,我设法让它工作。 Ran 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

如果您需要更多信息,请告诉我。

谢谢!

【问题讨论】:

【参考方案1】:

虽然我不能 100% 确定这是问题所在,但很有可能您的序列已过时。

在 Postgres 中执行此操作能否解决问题?

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

【讨论】:

确实,面临同样的问题。通过 pgAdmin 可以实现相同的解决方案:浏览到左侧窗格中的数据库和模式(确保序列在文件 -> 首选项 -> 浏览器 -> 节点中可见)。然后选择相关表的Sequence:右键->Properties。现在在定义 -> 当前值中设置正确的值并保存。可能你需要增加价值。使其比表中看到的最大 PK 值高 1。 它说'django_content_type_id_seq'列不存在,但表确实存在,我不明白是什么列?你能帮忙吗 也许你忘记了@reindeer 的引号?【参考方案2】:

这通常意味着您的主键序列不同步。这可能是由于迁移不当等造成的。 解决这个问题; 1.启动dbshel​​lpython 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;

【讨论】:

太棒了,这对我有帮助!【参考方案3】:

这意味着您的数据库中有过时的序列(不正确的先前迁移或不同版本代码之间的跳转会导致以混乱的顺序应用迁移可能会导致这种损坏状态)。要快速解决此问题,您可以手动更新数据库中的值。

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

我使用的解释:

我使用的是通过ListCreateAPIViewModelSerializer 连接的 Django RestFramework。无论出于何种原因,OneToOneFieldUNIQUE 附加到连接表之一blahmodule_blahthing_blahstuff_id,(我实际上不确定它是否是连接表,这是一个假设),但无论 django 切换到带有 QuerySet 的 ForeignKey 返回,解决了我的问题。

相关:

What's the difference between django OneToOneField and ForeignKey? https://www.postgresql.org/docs/11/ddl-constraints.html

就上面的实际问题而言:

架构:

-- 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 上的哈希值和主键可能会变得混乱。

【讨论】:

【参考方案5】:

受 Wolph 的启发,这是我的解决方案。

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

【讨论】:

我还发现,如果我除了反复重新运行 ./manage.py migrate 之外什么都不做,它最终会起作用。

以上是关于django.db.utils.IntegrityError:重复键值违反唯一约束“django_content_type_pkey”的主要内容,如果未能解决你的问题,请参考以下文章