django 迁移 - 具有多个开发分支的工作流
django migrations - workflow with multiple dev branches
我很好奇其他 Django 开发人员如何通过迁移管理多个代码分支(例如 git)。
我的问题如下:
- 我们在 git 中有多个功能分支,其中一些带有 django 迁移(其中一些更改字段,或完全删除它们)
- 当我切换分支(使用 git checkout some_other_branch
)时,数据库并不总是反映新代码,所以我 运行 进入 "random" 错误,其中 db table 列不存在等等...
现在,我只是删除数据库并重新创建它,但这意味着我必须重新创建一堆虚拟数据才能重新开始工作。我可以使用固定装置,但它需要跟踪哪些数据去了哪里,这有点麻烦。
是否有 good/clean 处理此用例的方法?我在想 post-checkout
git 挂钩脚本可以 运行 必要的迁移,但我什至不知道迁移回滚是否完全可能。
迁移回滚是可能的,通常由 django 自动处理。
考虑以下模型:
class MyModel(models.Model):
pass
如果你运行python manage.py makemigrations myapp
,它会生成初始迁移脚本。
然后,您可以 运行 python manage.py migrate myapp 0001
应用此初始迁移。
如果之后您向模型中添加一个字段:
class MyModel(models.Model):
my_field = models.CharField()
然后重新生成一个新的迁移,并应用它,你仍然可以回到初始状态。只是 运行
python manage.py migrate myapp 0001
并且 ORM 将倒退,删除 新字段。
处理数据迁移时比较棘手,因为你必须编写前向和后向代码。
考虑通过 python manage.py makemigrations myapp --empty
创建的空迁移,
你最终会得到这样的结果:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
def forward(apps, schema_editor):
# load some data
MyModel = apps.get_model('myapp', 'MyModel')
while condition:
instance = MyModel()
instance.save()
def backward(apps, schema_editor):
# delete previously loaded data
MyModel = apps.get_model('myapp', 'MyModel')
while condition:
instance = MyModel.objects.get(myargs)
instance.delete()
class Migration(migrations.Migration):
dependencies = [
('myapp', '0003_auto_20150918_1153'),
]
operations = [
migrations.RunPython(forward, backward),
]
对于纯数据加载迁移,通常不需要向后迁移。
但是当您更改架构并更新现有行时
(比如将列中的所有值转换为 slug),您通常必须编写向后步骤。
在我们的团队中,我们尽量避免同时处理相同的模型以避免冲突。
如果不可能,并且创建了两个具有相同编号(例如 0002)的迁移,
您仍然可以重命名其中之一以更改它们的应用顺序(还记得更新
迁移 class 到您的新订单的 dependencies
属性)。
如果您最终在不同的功能中同时处理相同的模型字段,
你仍然会有麻烦,但这可能意味着这些功能是相关的,应该处理
一起在一个分支中。
对于 git-hooks 部分,可能会写一些东西,假设你在分支 mybranch
并想查看另一个功能分支 myfeature
:
- 就在切换之前,您将当前应用的迁移列表转储到
临时文件
mybranch_database_state.txt
- 然后,您应用
myfeature
分支迁移,如果有的话
- 然后,当回头检查
mybranch
时,您重新应用以前的数据库状态
通过查看转储文件。
然而,这对我来说似乎有点 hackish,并且可能真的很难正确处理所有场景:
变基、合并、挑选樱桃等
在发生迁移冲突时处理它们对我来说似乎更容易。
我对此没有很好的解决方案,但我感到很痛苦。
一个post-checkout hook 来不及了。如果你在A分支上,check out分支B,B的迁移比A少,回滚信息只在A,需要运行 before checkout。
我在多次提交之间跳转试图找到错误的根源时遇到了这个问题。我们的数据库(即使在开发 trim)是巨大的,所以删除和重新创建是不切实际的。
我正在为 git 设计一个包装器-结帐:
- 记录每个 INSTALLED_APPS
的最新迁移
- 查看请求的分支并记录那里的最新迁移
- 对于#1 中的迁移比#2 中的迁移更早的每个应用程序,迁移回#2 中的最高迁移
- 查看新分支
- 对于#2 中的迁移早于#1 的每个应用,向前迁移
一个简单的编程问题!
对于简单的更改,我依赖于迁移回滚,正如 所讨论的那样。
但是,如果我知道一个功能分支将涉及高度侵入性的数据库更改,或者如果它将涉及大量数据迁移,我希望尽快创建本地(或远程开发)数据库的克隆当我开始新分支时。这可能并不总是很方便,但特别是对于使用 sqlite 的本地开发,只需复制一个文件(不受源代码控制)。
新分支上的第一次提交然后更新我的 Django settings (local/dev) 以使用克隆的数据库。这样,当我切换分支时,会自动选择正确的数据库。无需担心回滚架构更改、丢失数据等。没有复杂的东西。
功能分支完全合并后,可以删除克隆的数据库。
我很好奇其他 Django 开发人员如何通过迁移管理多个代码分支(例如 git)。
我的问题如下:
- 我们在 git 中有多个功能分支,其中一些带有 django 迁移(其中一些更改字段,或完全删除它们)
- 当我切换分支(使用 git checkout some_other_branch
)时,数据库并不总是反映新代码,所以我 运行 进入 "random" 错误,其中 db table 列不存在等等...
现在,我只是删除数据库并重新创建它,但这意味着我必须重新创建一堆虚拟数据才能重新开始工作。我可以使用固定装置,但它需要跟踪哪些数据去了哪里,这有点麻烦。
是否有 good/clean 处理此用例的方法?我在想 post-checkout
git 挂钩脚本可以 运行 必要的迁移,但我什至不知道迁移回滚是否完全可能。
迁移回滚是可能的,通常由 django 自动处理。
考虑以下模型:
class MyModel(models.Model):
pass
如果你运行python manage.py makemigrations myapp
,它会生成初始迁移脚本。
然后,您可以 运行 python manage.py migrate myapp 0001
应用此初始迁移。
如果之后您向模型中添加一个字段:
class MyModel(models.Model):
my_field = models.CharField()
然后重新生成一个新的迁移,并应用它,你仍然可以回到初始状态。只是 运行
python manage.py migrate myapp 0001
并且 ORM 将倒退,删除 新字段。
处理数据迁移时比较棘手,因为你必须编写前向和后向代码。
考虑通过 python manage.py makemigrations myapp --empty
创建的空迁移,
你最终会得到这样的结果:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
def forward(apps, schema_editor):
# load some data
MyModel = apps.get_model('myapp', 'MyModel')
while condition:
instance = MyModel()
instance.save()
def backward(apps, schema_editor):
# delete previously loaded data
MyModel = apps.get_model('myapp', 'MyModel')
while condition:
instance = MyModel.objects.get(myargs)
instance.delete()
class Migration(migrations.Migration):
dependencies = [
('myapp', '0003_auto_20150918_1153'),
]
operations = [
migrations.RunPython(forward, backward),
]
对于纯数据加载迁移,通常不需要向后迁移。 但是当您更改架构并更新现有行时 (比如将列中的所有值转换为 slug),您通常必须编写向后步骤。
在我们的团队中,我们尽量避免同时处理相同的模型以避免冲突。
如果不可能,并且创建了两个具有相同编号(例如 0002)的迁移,
您仍然可以重命名其中之一以更改它们的应用顺序(还记得更新
迁移 class 到您的新订单的 dependencies
属性)。
如果您最终在不同的功能中同时处理相同的模型字段, 你仍然会有麻烦,但这可能意味着这些功能是相关的,应该处理 一起在一个分支中。
对于 git-hooks 部分,可能会写一些东西,假设你在分支 mybranch
并想查看另一个功能分支 myfeature
:
- 就在切换之前,您将当前应用的迁移列表转储到
临时文件
mybranch_database_state.txt
- 然后,您应用
myfeature
分支迁移,如果有的话 - 然后,当回头检查
mybranch
时,您重新应用以前的数据库状态 通过查看转储文件。
然而,这对我来说似乎有点 hackish,并且可能真的很难正确处理所有场景: 变基、合并、挑选樱桃等
在发生迁移冲突时处理它们对我来说似乎更容易。
我对此没有很好的解决方案,但我感到很痛苦。
一个post-checkout hook 来不及了。如果你在A分支上,check out分支B,B的迁移比A少,回滚信息只在A,需要运行 before checkout。
我在多次提交之间跳转试图找到错误的根源时遇到了这个问题。我们的数据库(即使在开发 trim)是巨大的,所以删除和重新创建是不切实际的。
我正在为 git 设计一个包装器-结帐:
- 记录每个 INSTALLED_APPS 的最新迁移
- 查看请求的分支并记录那里的最新迁移
- 对于#1 中的迁移比#2 中的迁移更早的每个应用程序,迁移回#2 中的最高迁移
- 查看新分支
- 对于#2 中的迁移早于#1 的每个应用,向前迁移
一个简单的编程问题!
对于简单的更改,我依赖于迁移回滚,正如
但是,如果我知道一个功能分支将涉及高度侵入性的数据库更改,或者如果它将涉及大量数据迁移,我希望尽快创建本地(或远程开发)数据库的克隆当我开始新分支时。这可能并不总是很方便,但特别是对于使用 sqlite 的本地开发,只需复制一个文件(不受源代码控制)。
新分支上的第一次提交然后更新我的 Django settings (local/dev) 以使用克隆的数据库。这样,当我切换分支时,会自动选择正确的数据库。无需担心回滚架构更改、丢失数据等。没有复杂的东西。
功能分支完全合并后,可以删除克隆的数据库。