无法在django中对更改的模型应用迁移

6rqinv9w  于 2023-01-14  发布在  Go
关注(0)|答案(2)|浏览(230)

我是django新手,我已经修改了我已经创建的Django模型中的一些字段,但是当我尝试在它上面应用迁移时,它显示了这样的消息:

It is impossible to add a non-nullable field 'name' to table_name without specifying a default. This is because the database needs something to populate existing rows.
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit and manually define a default value in models.py.

虽然我已经从数据库中删除了该表的数据。但由于该字段必须存储唯一值,因此无法设置其默认值。是否需要删除与该表相关的先前迁移文件?
我已经应用了数据迁移,但再次应用迁移时仍然出现相同的错误:

def add_name_and_teacher(apps, schema_editor):
    Student = apps.get_model('app_name', 'Student')
    Teacher = apps.get_model('app_name', 'Teacher')
    for student in Student.objects.all():
        student.name = 'name'
        student.teacher = Teacher.objects.get(id=1)
        student.save()

class Migration(migrations.Migration):

    dependencies = [
        ('app', '0045_standup_standupupdate'),
    ]

    operations = [
        migrations.RunPython(add_name_and_teacher),
    ]
lf3rwulv

lf3rwulv1#

所以,在你有一个可以为空的字段“name”之前,这意味着可以把null设置为那个字段的值。
如果向该字段添加一个非空约束(null=False),并运行迁移,则会从数据库中得到一个完整性错误,因为该表中的某些行将null设置为该字段的值。
如果你刚做了两次迁移,第一次添加了一个可空字段,但后来又想起来它不能为空,于是又添加了非空约束,那么你应该简单地恢复迁移并删除前一次迁移,这是最干净的解决方案。
您可以通过运行python manage.py migrate <app name> <the migration that you want to keep>进行恢复
然后,您只需删除新迁移并再次运行python manage.py makemigrations
如果带有可空字段的迁移是很早就定义的,并且那里已经有数据,并且不可能删除该迁移,那么您将需要弄清楚如何填充该数据。既然您说还有唯一约束,那么您不能只提供默认值,因为这会导致该约束出现问题。
我的建议是编辑迁移文件并添加migrations.RunSQL,您可以在其中编写自定义SQL代码,该代码将向字段中插入值。确保将RunSQL操作放在添加非空约束的操作之前(应为AlterFieldAddConstraint),因为它们是按顺序运行的。
您也可以使用migrations.RunPython,但我更喜欢RunSQL,因为将来代码的更改可能会破坏您的迁移,这是一个麻烦的处理。
RunSQL文档

ws51t4hk

ws51t4hk2#

是否从表中清除数据并不重要,因为如果模型的表存在,此消息将是Django模型的默认响应。2您可以手动在模型中添加字段并伪造迁移。3或者您可以考虑在迁移中设置默认值(正如prompt所说)。放置默认值并不意味着它会将表中的默认值应用于新条目。只有在迁移过程中更新表中的现有行时才使用此值,以简化迁移过程。
除此之外,您可以考虑使用数据迁移,它将创建空迁移文件,您可以在其中对数据进行任何更改(例如为字段生成新名称)。

相关问题