Django中的Unkown IntegrityError

时间:2017-02-19 20:01:14

标签: python django

所以我有这个小项目通过DjangoLatex创建账单,直到今天才能完美运作。现在当我尝试添加另一个客户时,Django抛出

duplicate key value violates unique constraint "kunden_kundearbeitsamt_pkey"
DETAIL:  Key (id)=(4) already exists.

<小时/> 这些是有问题的模型定义:

class Kunde(models.Model):
    name = models.CharField('Name', max_length = 200)
    vorname = models.CharField('Vorname', max_length = 200)
    geburtsdatum = models.DateField('Geburtsdatum', max_length = 200)
    untersuchungsdatum = models.DateField('Untersuchungsdatum', max_length = 200)

    class Meta:
        abstract = True

class KundeArbeitsamt(Kunde):
    kundennummer = models.CharField('Kundennummer', max_length = 100)
    bglnummer = models.CharField('BGL-Nummer', max_length = 100)
    empfaenger = models.ForeignKey('rechnungen.NumberToEmpfaenger', blank = True, null = True)

    class Meta:
        verbose_name = "Proband Arbeitsamt"
        verbose_name_plural = "Proband Arbeitsamt"

    def __str__(self):
        return '{}, {}'.format(self.name, self.vorname)

<小时/> 创建对象的管理部分(没什么特别的,我猜):

from django.contrib import admin
from .models import KundeArbeitsamt

class KundeArbeitsamtAdmin(admin.ModelAdmin):
    ordering = ('name',)

admin.site.register(KundeArbeitsamt, KundeArbeitsamtAdmin)

我发誓,我没有对数据库(Postgres)进行任何迁移或其他更改。 Django正在处理对象的创建。导致此错误的原因是什么以及如何解决?

1 个答案:

答案 0 :(得分:1)

您的数据库引发此错误,因为django想要添加一个已使用ID(=4)的新列。

要进一步调查,您需要找到负责创建ID的应用部分。 Django通常将此任务委托给您的数据库。对于postgres,使用数据类型serial。 Postgres为此目的使用所谓的序列,并为您生成并执行以下SQL:

CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
    colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;

我现在开始检查数据库的健全状况:

-- views contents of the table
SELECT * FROM kunden_kundearbeitsamt;
-- check the sequence
select currval('kunden_kundearbeitsamt_id_seq');

如果第一个显示4个ID为1,2,3和4的记录,序列以4个答案,则一切正常。我将继续使用django源来弄清楚为什么他们在不依赖序列的情况下在对象创建时传递ID。在这种情况下,django shell可能是一个很好的起点。

否则我会修复序列并问自己这是怎么回事,因为postgres在这一点上几乎不会出错。

SELECT setval('kunden_kundearbeitsamt_id_seq', (SELECT max(id) FROM kunden_kundearbeitsamt));