如何压制最近的Django迁移?

时间:2016-10-13 18:41:10

标签: django django-migrations

在Django的迁移代码中,有一个squashmigrations命令,其中:"将app_label的迁移范围扩展到包括migration_name在内的migration_name更少如果可能的话,迁移。"

所以,如果你想压缩前5次迁移,这将有所帮助。

从特定@Service public class ClassB { private ClassA classA; @Autowired public ClassB(ClassA classA) { this.classA = classA; } public void useClassAObjectHere(){ classA.callMethodOnObjectA(); } } 开始压缩的最佳方法是什么?

在我目前正在开展的项目中,我们添加了5-10个新的迁移文件,因为我们添加了新功能。我们将立即部署整个项目,看起来单独运行这些将花费太长时间。我想将此项目的所有迁移压缩到一次迁移中并测试运行时间。

4 个答案:

答案 0 :(得分:43)

python manage.py squashmigrations <appname> <squashfrom> <squashto>

python manage.py help squashmigrations

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

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

答案 1 :(得分:9)

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

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

此外:

  

与此相关的轻微复杂情况是,如果有自定义的RunPython代码,它将不会包含在makemigrations创建的新迁移中

答案 2 :(得分:0)

我创建了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内,您将找到一个{1-5}迁移名称的replaces = [..]。如果您删除了所有迁移,并对Migration.operations = [..]执行了./manage.py makemigrations和任何RunSQL / RunPython,也会发现一个elidable=False,其中包含了您期望的一切。如果您部署到缺少迁移1-5的任何环境,它将从源应用它,而不使用0006 AT ALL。 (这是标准的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

再次挤压。这次将发生以下情况。 replaces = [..]内部的所有内容都将被删除。 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

再次开始循环。

答案 3 :(得分:0)

[如果您使用的是 Django 1.8 ,并且需要部分地压缩迁移]

在Django 1.9中, squash migrations 命令具有从FROM-TO压缩迁移的功能

这是Django 1.9版本的 squashmigrations.py https://github.com/django/django/blob/stable/1.9.x/django/core/management/commands/squashmigrations.py

您需要

  • 将其放在您的项目中,位于/-package-/app-/management/commands/
  • 重命名为squashmigrations19.py
  • 运行./manage.py squashmigrations19 -your-app- 0002 0003