Django 迁移无法删除字段

Django migration fails to remove field

我正在使用 Python 3.8.4、Django 2.2.3、SQLite 3.32.3。

当我 运行 python manage.py makemigrations 时,Django 创建了一个包含以下操作的迁移文件,其中包括成功执行的其他操作)。

migrations.RemoveField(
    model_name='essayrequirement',
    name='program',
),

program字段删除前声明如下:

program = models.ForeignKey(UndergraduateProgram, on_delete=models.CASCADE, related_name="essay_set", null=True, blank=True)

但是,当我尝试 运行 迁移 (python manage.py migrate) 时,出现错误 django.core.exceptions.FieldDoesNotExist: NewEssayRequirement has no field named 'program'。 (似乎 NewEssayRequirement 是在应用迁移过程中创建的临时 table,它应该在迁移完成之前替换 EssayRequirement table。)

在 SQLite 数据库本身之前 应用迁移确认 program 字段确实存在——它的列存在。此外,我已经尝试从迁移中删除此操作,当然下一次调用 makemigrations 会将其恢复。在这种情况下 migrateing 时会发生同样的错误。

有趣的是,在同一模型上还有另一个名为 non_undergrad_program 的字段,不同之处仅在于 ForeignKey 指向的位置。有问题的迁移也删除了这个字段,但出于某种原因,这样做成功了:

migrations.RemoveField(
    model_name='essayrequirement',
    name='non_undergrad_program',
),

我已经在这个问题上停留了一段时间,因为它或多或少地破坏了我们应用程序向前推进的迁移。我什至找不到忽略该操作的方法,并继续忽略该列的存在。

原来是因为我删除的字段存在唯一性约束,我忽略了这一点:

class Meta:
    constraints = [
        models.UniqueConstraint(fields=['program', 'index'], name='unique_essay')
    ]

此约束是 FieldDoesNotExist 异常的来源。通过调整约束列表并重新进行迁移,然后将这些生成的操作添加到有问题的迁移文件中,问题得到了解决。