Как сделать ваши пользовательские миграции django обратимыми?
Моя первоначальная проблема заключалась в том, что в таблице db с 60M строк мне нужно преобразовать тип поля из булева в целочисленный. Я подумал о создании пользовательской миграции 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().
Идея создания резервного поля заключается в восстановлении прежнего состояния базы данных.
я отредактировал свой ответ после ваших комментариев - в момент, когда 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',
),
]