应用以下迁移后,
class Migration(migrations.Migration):
dependencies = [
('outlets', '0009_auto_20190920_1155'),
]
operations = [
migrations.AlterField(
model_name='outlet',
name='country',
field=models.IntegerField(choices=[(1, 'UAE'), (2, 'India')],
verbose_name='Country'),
),
]
发生以下错误,
return self.cursor.execute(sql, params)
django.db.utils.DataError: invalid input syntax for integer: "United States"
这是因为我将CharField更改为IntegerField,并且以下数据“美国”已存在于db中,而且我读到类似的问题,Django迁移无法处理此类更改。
有什么方法可以执行此操作,而不删除现有数据?
答案 0 :(得分:1)
如果您希望一切顺利,则需要将数据突变整合到迁移中
作为示例:
from django.db import migrations, models
import django.db.models.deletion
def migrate_country(apps, schema_editor):
Outlet = apps.get_model('your_app_name', 'Outlet')
# You can either do
Outlet.objects.all().update(
temp_country= 'what_ever_update you want'
)
# Or
for outlet in Outlet.objects.all():
outlet.temp_country='your_transformation_result'
outlet.save() # Please note django will use it's save method.
# Your eventual override will just be ignore
def reverse_country(apps, schema_editor):
"""
Do want you want when rolling back your migration
"""
....
class Migration(migrations.Migration):
dependencies = [
...
]
operations = [
migrations.AddField(
model_name='Outlet',
name='temp_outlet',
name='country',
field=models.IntegerField(choices=[(1, 'UAE'), (2, 'India')],
verbose_name='Country'),
),
# Now, you have temp_outlet available on your schema!
migrations.RunPython(migrate_country, reverse_country),
# We dump "old" field
migrations.RemoveField(
model_name='article',
name='outlet',
),
# We rename the 'temp' field as excpected!
migrations.RenameField(
model_name='Outlet',
old_name='oldname',
new_name='newname',
),
]
答案 1 :(得分:-2)
您需要在三个单独的迁移中执行此操作。
首先,添加IntegerField,其值为null = True或默认值为0。
第二,添加一个数据迁移,该数据迁移将在现有CharField中获取该值,查找匹配的整数值,并将其设置为新的IntegerField。
第三,删除CharField,重命名IntegerField并删除默认值/空值。