我是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),
]
2条答案
按热度按时间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
操作放在添加非空约束的操作之前(应为AlterField
或AddConstraint
),因为它们是按顺序运行的。您也可以使用
migrations.RunPython
,但我更喜欢RunSQL
,因为将来代码的更改可能会破坏您的迁移,这是一个麻烦的处理。RunSQL文档
ws51t4hk2#
是否从表中清除数据并不重要,因为如果模型的表存在,此消息将是Django模型的默认响应。2您可以手动在模型中添加字段并伪造迁移。3或者您可以考虑在迁移中设置默认值(正如prompt所说)。放置默认值并不意味着它会将表中的默认值应用于新条目。只有在迁移过程中更新表中的现有行时才使用此值,以简化迁移过程。
除此之外,您可以考虑使用数据迁移,它将创建空迁移文件,您可以在其中对数据进行任何更改(例如为字段生成新名称)。