如何判断迁移是否可逆?

How to tell whether migrations are reversible?

在我正在进行的项目中,我们运行 针对生产数据库的快照进行了一些测试。对于包括迁移在内的更改,我想应用迁移,运行 测试,然后反向迁移。

但是,并非所有迁移都是可逆的。我如何让 自动化 进程在应用它们之前检测是否所有必需的迁移都是可逆的?

几天没有答案后,我继续想出了一个解决方案。 This SO answer 是一个很好的起点。

from django.db.migrations.executor import MigrationExecutor
from django.db import connections, DEFAULT_DB_ALIAS

def are_migrations_reversible(target_migrations, database=DEFAULT_DB_ALIAS):
    """check if all migrations required to reach the target migrations are reversible

    `target_migrations` is an iterable of (app_label, migration_name) 2-tuples.
    """
    connection = connections[database]
    connection.prepare_database()
    executor = MigrationExecutor(connection)
    migration_plan = executor.migration_plan(list(target_migrations))

    return all(
        operation.reversible
        for (migration, is_backwards) in migration_plan
        for operation in migration.operations
    )

以上需要弄清楚目标迁移,这可以很容易地从 showmigrations 管理命令的输出中提取,或者通过进一步使用内部 Django 迁移代码来付出更多努力。