在我的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字段仍来自何处?
答案 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上效果更好。
对于错误,您要保存模型吗?或进行原始导入?