我最初的问题是,给定一个包含 60M 行的数据库表,我需要将字段类型从 bool 字段转换为整数字段。我想为此创建一个自定义 django 迁移(如果您有比这更好的方法,请告诉我),如下所示 -
def make_changes(apps, schema_editor):
vcs_model = apps.get_model('iot_app', 'AbstractVCSCompartmentData')
vcs_model.objects.select_related('vcsdata').all().update(charging_status_v2=F('charging_status'))
vcs_model.objects.select_related('vcsdata').all().update(charging_status_backup=F('charging_status')) # backup
class Migration(migrations.Migration):
dependencies = [
('iot_app', '0030_auto_20220225_1027.py'),
]
operations = [
migrations.AddField( # backup field
model_name='AbstractVCSCompartmentData',
name='charging_status_backup',
field=models.PositiveIntegerField(blank=True, null=True),
),
migrations.AddField(
model_name='AbstractVCSCompartmentData',
name='charging_status_v2',
field=models.PositiveIntegerField(blank=True, null=True),
),
migrations.RunPython(make_changes),
migrations.RemoveField(
model_name='AbstractVCSCompartmentData',
name='charging_status',
),
migrations.RenameField(
model_name='AbstractVCSCompartmentData',
old_name='charging_status_v2',
new_name='charging_status',
),
]
我想展开所有更改,即使我的自定义迁移可逆。
我已经经历过RunPython文档。但我很困惑如何在我的 reverse_code()
函数中添加新字段。
创建备份字段的想法是将数据库恢复到之前的状态。
鉴于该表中有 60M 行,这是正确的方法吗?不会暂时锁表吧?我想尽可能高效地做到这一点
最佳答案
我在您发表评论后编辑了我的答案 - 在还原步骤中执行 RunPython
时,charging_status
已重命名为 charging_status_v2
并且旧的 charging_status
字段存在。因此您可以直接从备份复制到 charging_status
def make_changes(apps, schema_editor):
vcs_model = apps.get_model('iot_app', 'AbstractVCSCompartmentData')
vcs_model.objects.select_related('vcsdata').all().update(charging_status_v2=F('charging_status'))
vcs_model.objects.select_related('vcsdata').all().update(charging_status_backup=F('charging_status')) # backup
def backwards(apps, schema_editor):
vcs_model = apps.get_model('iot_app', 'AbstractVCSCompartmentData')
vcs_model.objects.select_related('vcsdata').all().update(charging_status=F('charging_status_backup'))
class Migration(migrations.Migration):
dependencies = [
('iot_app', '0030_auto_20220225_1027.py'),
]
operations = [
migrations.AddField( # backup field
model_name='AbstractVCSCompartmentData',
name='charging_status_backup',
field=models.PositiveIntegerField(blank=True, null=True),
),
migrations.AddField(
model_name='AbstractVCSCompartmentData',
name='charging_status_v2',
field=models.PositiveIntegerField(blank=True, null=True),
),
migrations.RunPython(make_changes, backwards),
migrations.RemoveField(
model_name='AbstractVCSCompartmentData',
name='charging_status',
),
migrations.RenameField(
model_name='AbstractVCSCompartmentData',
old_name='charging_status_v2',
new_name='charging_status',
),
]
关于django - 如何使自定义 django 迁移可逆?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71855023/