模型修改后进行数据库迁移可能会遇到的问题
问题发生的情形
原来模型的字段:order_number = models.CharField('补货单号', max_length=20, unique=True, editable=False, blank=True)
去除blank=True
修改改为:order_number = models.CharField('补货单号', max_length=20, unique=True, editable=False)
然后进行数据迁移:
(venv) PS D:\Gitee\wms\baking_wms> python manage.py makemigrations store
It is impossible to change a nullable field 'order_number' on storereplenishmentorder to non-nullable without providing 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) Ignore for now. Existing rows that contain NULL values will have to be handled manually, for example with a RunPython or RunSQL operation.
3) Quit and manually define a default value in models.py.
Select an option:
分析与解决方法
当你尝试将一个原本允许为空(blank=True)的字段改为不允许为空(移除了 blank=True),Django 会提示你需要为现有数据提供一个默认值。这是因为数据库需要一个值来填充那些原本为空的行。
以下是解决这个问题的几种方法:
1. 提供一个默认值
如果你希望为所有现有的空值提供一个默认值,可以选择第一个选项。例如,你可以选择一个默认的补货单号,比如 "DEFAULT_ORDER_NUMBER"。
在提示中选择 1,然后输入默认值:
Select an option: 1
Please enter the default value now: DEFAULT_ORDER_NUMBER
Django 会为所有现有的空值填充这个默认值,并生成迁移文件。
2. 手动处理现有数据
如果你希望手动处理现有数据,可以选择第二个选项。这意味着你需要在迁移文件中添加一个 RunPython 或 RunSQL 操作来处理现有的空值。
在提示中选择 2,然后在迁移文件中手动添加处理逻辑。例如:
from django.db import migrations
def set_default_order_number(apps, schema_editor):
StoreReplenishmentOrder = apps.get_model('store', 'StoreReplenishmentOrder')
default_order_number = "DEFAULT_ORDER_NUMBER"
StoreReplenishmentOrder.objects.filter(order_number__isnull=True).update(order_number=default_order_number)
class Migration(migrations.Migration):
dependencies = [
('store', 'previous_migration_name'), # 替换为上一个迁移文件的名称
]
operations = [
migrations.RunPython(set_default_order_number),
]
3. 退出并手动定义默认值
如果你希望在模型中直接定义默认值,可以选择第三个选项。然后在模型中添加一个默认值。例如:
order_number = models.CharField('补货单号', max_length=20, unique=True, editable=False, default="DEFAULT_ORDER_NUMBER")
这样,Django 会在生成迁移文件时自动使用这个默认值填充现有的空值。
推荐方法
如果你希望快速解决问题,可以选择 方法 1,直接提供一个默认值。这种方法简单且快速。
如果你希望更灵活地处理现有数据,可以选择 方法 2,手动编写处理逻辑。
如果你希望在模型中明确指定默认值,可以选择 方法 3,但需要注意的是,一旦设置了默认值,所有新创建的记录都会使用这个默认值,除非你在创建时显式指定其他值。
注意事项
- 如果你选择提供默认值,确保这个默认值不会与现有的唯一性约束冲突(因为
order_number是unique=True)。 - 如果你选择手动处理现有数据,确保在迁移文件中正确处理所有空值,否则迁移可能会失败。
根据你的需求选择最适合的方法!

浙公网安备 33010602011771号