django - 如何使自定义 django 迁移可逆?

标签 django migration database-migration django-migrations

我最初的问题是,给定一个包含 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/

相关文章:

c# - Cookie 身份验证和 Asp Net Core 2.0 迁移

mysql - filemaker pro通过php导出和导入到mysql

python - Django 中用户的默认类型是什么?

python - 如何在 Django 模型中保存对象列表?

python - Django 的方法是什么?

django - 如何在南迁中访问 auth User 的 User.objects.create_user(...) ?

ruby-on-rails - 问题将数据库迁移到 Heroku - PG::UndefinedTable: ERROR: relation "users"does not exist

python - 如何跟踪线性工作流程中的步骤

python - 当情况并非如此时,Pylint-django 会引发有关 Django 未配置的错误(VSCode)

node.js - 没有文件的Sequelize迁移