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

时间:2013-10-02 10:45:52

标签: python django postgresql

遇到一个问题,当我运行'python manage.py syncdb'我正在一个相当古老的网站上工作时,我收到上述错误消息。它用postgres DB运行django 1.2.6。

运行没有安装南部,我设法让它工作。跑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 个答案:

答案 0 :(得分:41)

虽然我不是100%肯定这是问题,但你的序列很可能已经过时了。

在Postgres中执行此操作是否可以解决问题?

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

答案 1 :(得分:7)

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

答案 2 :(得分:1)

从沃尔夫的灵感中,这是我的解决方法。

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

答案 3 :(得分:1)

这表示数据库中的序列过时(先前的不正确迁移或在不同版本的代码之间跳转会导致以混乱的顺序应用迁移会导致此中断状态)。为了快速解决此问题,您可以手动更新数据库中的值。

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 :(得分:0)

我收到此错误:

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

可能的解决方案:

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

我正在使用的内容的说明:

我使用的是Django RestFramework,它通过ListCreateAPIViewModelSerializer连接在一起。无论出于何种原因,OneToOneField都会将UNIQUE附加到其中一个联接表blahmodule_blahthing_blahstuff_id(实际上我不确定是否是联接表,这是一个假设),但是无论如何在django中发生了切换到带有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上的哈希和主键可能会变得混乱。