代码之家  ›  专栏  ›  技术社区  ›  Doug Harris

如何压制最近的Django迁移?

  •  86
  • Doug Harris  · 技术社区  · 10 年前

    在Django的迁移代码中 squashmigrations 命令:“挤压迁移 app_label 直至并包括 migration_name 尽可能减少迁移。”

    因此,如果您想压制前5次迁移,这将有所帮助。

    从一个特别的开始,最好的方法是什么 migration_name ?

    在我目前正在进行的一个项目中,我们添加了5-10个新的迁移文件,同时添加了新的功能。我们将立即部署整个项目,单独运行这些项目似乎需要太长时间。我想将这个项目的所有迁移压缩到一个迁移中,并测试运行时间。

    4 回复  |  直到 10 年前
        1
  •  154
  •   A---    10 年前
    python manage.py squashmigrations <appname> <squashfrom> <squashto>
    
    python manage.py help squashmigrations
    

    https://docs.djangoproject.com/en/dev/topics/migrations/#migration-squashing

    这将使您能够更细粒度地控制要挤压哪些迁移,并让您保持更清晰的提交历史记录。删除并重新创建所有迁移可能会导致其他问题,如循环依赖关系,具体取决于模型的构造方式。

        2
  •  27
  •   Community Mohan Dere    9 年前

    您可以删除迁移文件并运行 makemigrations 再一次如果您有一个使用这些的开发人员部署,您应该 migrate back 到您删除的第一个之前的一个。

    此外,如果出现问题,最好先提交代码。

    也:

    这有点复杂,因为如果有自定义的RunPython代码,它不会包含在makemigrations创建的新迁移中

        3
  •  5
  •   pymen    4 年前

    南瓜迁徙 命令是在Django 1.9中引入的

    如果您正在使用 Django 1.8 你需要

        4
  •  4
  •   Javier Buzzi    6 年前

    我创造 django-squash https://pypi.org/project/django-squash/ 作为一种不必在每个应用程序级别或更糟糕的每个应用程序特定迁移级别上处理迁移的方法,并在每个项目级别上处理它。这个想法是希望在某个时候将它集成到核心Django中。

    基本思路:

    • 你有一个产品,没有其他人可以增强的开源,但你的团队,你处理它。
    • 每次发布后,您都希望取消在上一版本中进行的所有迁移,并开始新的迁移,因为您的产品已经从上一版本和数据模型演变而来。
    • 当你挤压时,它会查看你之前是否已经挤压过,如果有,它会删除任何在你的代码库中不再有业务的非常旧的迁移。最后,创建一个迁移的新快照,并保留您的迁移。

    例子:

    /app1/migrations/__init__.py
    /app1/migrations/0001_initial.py
    /app1/migrations/0002_created_user_model.py
    /app1/migrations/0003_added_username.py
    /app1/migrations/0004_added_password.py
    /app1/migrations/0005_last_name.py
    

    你已经把它们都应用了。

    但是,每次运行测试时,这些步骤中的每一个都需要运行,占用宝贵的时间。所以我们把它压扁了。新目录如下所示:

    /app1/migrations/__init__.py
    /app1/migrations/0001_initial.py
    /app1/migrations/0002_created_user_model.py
    /app1/migrations/0003_added_username.py
    /app1/migrations/0004_added_password.py
    /app1/migrations/0005_last_name.py
    /app1/migrations/0006_squash.py
    

    在…内 0006_squash.py 你会发现 replaces = [..] 使用迁移1-5的名称 Migration.operations = [..] 如果您删除了所有迁移并执行了 ./manage.py makemigrations +任何 RunSQL / RunPython 具有 elidable=False .如果您部署到缺少任何迁移1-5的环境,它将从源应用它,而根本不使用0006。(这是标准的Django迁移)

    随着时间的推移,现在您的迁移看起来像这样:

    /app1/migrations/__init__.py
    /app1/migrations/0001_initial.py
    /app1/migrations/0002_created_user_model.py
    /app1/migrations/0003_added_username.py
    /app1/migrations/0004_added_password.py
    /app1/migrations/0005_last_name.py
    /app1/migrations/0006_squash.py
    /app1/migrations/0007_change_username_to_100_char.py
    /app1/migrations/0008_added_dob.py
    

    你又挤了。这次将发生以下情况。里面有什么 替换=[…] 将被删除。 0006_squash.py 将被修改为具有 replaces 是一个空列表。最后,将使用新的更改重新创建壁球。总而言之,将看起来像这样:

    /app1/migrations/0006_squash.py
    /app1/migrations/0007_change_username_to_100_char.py
    /app1/migrations/0008_added_dob.py
    /app1/migrations/0009_squash.py
    

    再次开始循环。