Postgres14 上的 Django4。最新版本 2023 年 11 月这个bug困扰了我一整天
没有找到有用的解决方案。因此写一个公会,可以方便将来的访问者。
所以Postgres与SQLite3的不同之处主要在于主键。如果你们有一对一的关系
app = models.OneToOneField(project)
在 SQLite3 中,当你调用
app.pk == app.project.pk
时,它总是 true。这允许你写这样的东西:user = user.objects.get(pk=profile_pk)
,因为它们都是一致的。
但是Postgres不同,一对一将不再有一致的主键,这意味着你必须指定
app = models.OneToOneField(project, primary_key=True)
,才能使两个表具有一致的pks,以支持你编写的视图逻辑而无需手动更改它们(比如通过一对一 pk 获取另一个模型实例,因为它们应该是相同的)。
但是如果你定义了其他现有的一对一关系,这是不可能的:例如模型A在模型B上有一个一对一的字段,并且具有一致的pks,并且模型B与模型C有一对一的字段,并且没有一致的一致的峰。这里后端 sql 执行器默认会尝试实例化另一个 pk 字段以允许您建立此数据库关系。然而,这被认为是 django 无法管理的做法,因此提出了一个例外:
multiple primary keys not allowed
。
此外,如果您尝试在迁移的同时声明引用该
one-to-one messed up
表的 pk 的新模型模式,那么它将是 foreign key constraint does not exist
。
幸好有解决方案,无需删除数据库。
python manage.py migrate app 0002_initial
删除生成的新迁移文件,仔细检查模型,最好删除该模型中所有带有
primary_key=True
的一对一字段。
进行迁移并迁移该应用程序。