unique_together不替换主键

时间:2019-06-18 11:51:32

标签: django postgresql

在我的Django应用中,我想插入带有复合主键的记录。显然,这应该可以通过使用“ unique_together”来实现。我很确定这段代码过去是有效的,但是由于某种原因,它似乎现在无法正常工作。该代码曾经在Linux VM上运行,现在我将其托管在Google App Engine中。但是,我不知道这怎么可能是导致此错误的原因。

class TermsAndConditionsDocument(models.Model):
    organization = models.ForeignKey(Organization, on_delete=models.CASCADE, verbose_name=_("Organization"))
    language = models.CharField(_('Language'),choices=LANGUAGE_CHOICES, max_length=5, help_text=_("The language of the content."))
    content = models.TextField()

    class Meta:
        unique_together = ('organization', 'language')

错误:

IntegrityError at /transactions/settings/terms_and_conditions

null value in column "id" violates not-null constraint
DETAIL:  Failing row contains (null, nl-BE, <p>B</p>, 10).

根据我所读的内容,使用“ unique_together”应该会导致Django不需要或包含ID作为主键。我检查了数据库,并且ID字段确实存在。我不明白数据库约束和ID字段仍来自何处?

2 个答案:

答案 0 :(得分:0)

很明显,正如注释中指出的那样,即使您不需要它,也总是添加主键“ id”字段。它本来应该挡住您的,所以您甚至都不会注意到它的存在。就我而言,它要求我在创建新记录时为其赋予一个值,而这并不是事情应该如何工作的。

前一段时间,我将此数据库从一个Postgres数据库迁移到另一个Postgres数据库。为此,我使用了SQL转储和加载方法。在迁移过程中似乎丢失了一些序列。

由于没有序列,因此某些字段现在缺少自动递增功能,这说明了插入时出现IntegrityError。

为了解决这个问题,我做了以下事情:

1)导出当前数据:

manage.py dumpdata > data.json

2)删除您的数据库并创建一个新的空数据库。

3)运行数据库迁移:

manage.py migrate

4)再次加载数据,但不包括Django已经重新创建的一些默认数据。

manage.py loaddata --exclude auth.permission --exclude contenttypes data.json 

此过程似乎在重新创建序列的同时还保留了数据。

答案 1 :(得分:-1)

unique_together仅创建数据库约束(https://docs.djangoproject.com/en/2.2/ref/models/options/#unique-together)。

您可以使用选项primary_key https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.Field.primary_key创建自定义主键,但是只能在一个字段中执行此操作。

但是我建议保留自动增量id字段,这在Django上效果更好。

对于错误,您要保存模型吗?或进行原始导入?