ChatGPT解决这个技术问题 Extra ChatGPT

如何压缩最近的 Django 迁移?

在 Django 的迁移代码中,有一个 squashmigrations 命令:“如果可能,将 app_label 的迁移压缩到并包括 migration_name 到更少的迁移中。”

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

从特定的 migration_name 开始压缩的最佳方法是什么?

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

对此进行更新 - 在压缩和测试之后,它花了太长时间。其中很大一部分是因为对于我添加的每一列,MySQL 会复制整个表,添加列,然后重命名表。我使用 sqlmigrate 查看将运行的 SQL,并将四个单独的 ALTER TABLE 语句组合成一个具有四个 ADD COLUMN 部分的语句,并使用带有 state_operations 参数的 migrations.RunSQL 运行它,以保持迁移状态逻辑满意。

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

python manage.py help squashmigrations

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

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


好答案——如果运行 Django 1.9 或更新版本。可悲的是,这个项目是在 1.8
这得到了公认的答案,因为它使用现代版 Django 的原生功能。那些仍在使用 1.9 之前的 Django 版本的人应该看到 Dan 的回答。
为了省去阅读所有长迁移文件名的麻烦。您可以使用前 4 位数字,例如 manage.py squashmigrations myapp 0011 0015 将迁移 0011_auto_someintshere 压缩到 0015_auto_someintshere
C
Community

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

此外,最好先提交代码,以防出现问题。

还:

稍微复杂的是,如果有自定义 RunPython 代码,它将不会包含在 makemigrations 创建的新迁移中


如此明智和明显。我也会在一个分支中做:-)
稍微复杂的是,如果有自定义 RunPython 代码,它将不会包含在 makemigrations 创建的新迁移中
如果您删除选定的迁移(比如 __init__ 之后的所有迁移),然后运行 makemigrations 并看到类似 You have 1 unapplied migration(s) 的消息,您可以运行 ./manage.py migrate --fake 来“伪造”迁移(尽管其他团队成员将获得完整移民)。
我一直想知道这一点。我一直在为进行如此多的迁移而苦苦挣扎,但Django recommends it explicitly。我想这取决于场景,例如 RunPython、您的开发团队成员等。感谢您在混乱中指出显而易见的事情。
J
Javier Buzzi

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

基本思路:

你有一个产品,没有其他人可以增强的开源,但是你的,你的团队,你来处理它。

在每个版本之后,您都希望压缩您在过去版本中所做的所有迁移并开始一个新版本,因为您的产品已经从上一个版本和您的数据模型演变而来。

你 squash,它会查看你之前是否已经 squash,如果有,它会删除所有在你的代码库中没有业务的非常旧的迁移。最后,为您的迁移创建一个新快照,并保留您现有的迁移。

您将在每个版本/当您觉得您的测试在运行所有迁移时花费太长时间时执行此操作。

例子:

/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 = [..]。如果您删除所有迁移并使用 elidable=False 执行 ./manage.py makemigrations + any RunSQL/RunPython,您还会发现 Migration.operations = [..] 包含您所期望的所有内容。如果您部署到缺少任何迁移 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

你又压扁了。这次会发生以下情况。 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

再次开始循环。


p
pymen

Django 1.9 中引入了 Squash 迁移命令

如果您使用的是 Django 1.8,则需要

从 Django 1.9 版本 https://github.com/django/django/blob/stable/1.9.x/django/core/management/commands/squashmigrations.py 获取 squashmigrations.py

将它放在你的项目中,在 /-package-/-app-/management/commands/ 下

重命名为 squashmigrations19.py

运行 ./manage.py squashmigrations19 -app- 0002 0003


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅