我很好奇其他django开发人员如何通过迁移管理多个代码分支(例如,在git中)。
我的问题如下:
-我们在git中有多个功能分支,其中一些具有django迁移功能(其中一些更改了字段或完全删除了它们)
-当我切换分支(使用git checkout some_other_branch
)时,数据库并不总是反射(reflect)新代码,因此我遇到“随机”错误,其中不再存在db表列,等等。
现在,我只是删除数据库并重新创建它,但这意味着我必须重新创建一堆虚拟数据才能重新开始工作。我可以使用固定装置,但是它需要跟踪数据去往何处,这有点麻烦。
有没有一种很好/干净的方法来处理这个用例?我在想post-checkout
git hook脚本可以运行必要的迁移,但是我什至不知道迁移回滚是否完全可能。
最佳答案
迁移回滚是可能的,并且通常由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)的迁移,
您仍然可以重命名其中之一来更改应用顺序(也请记住要更新
迁移类上的
dependencies
属性更改为您的新订单)。如果最终您同时在不同的功能中使用相同的模型字段,
您仍然会遇到麻烦,但这可能意味着这些功能是相关的,应该加以处理
一起在一个分支中。
对于git-hooks部分,可能可以写点东西,假设您在
mybranch
分支上并想查看另一个功能分支
myfeature
:临时文件
mybranch_database_state.txt
myfeature
分支迁移mybranch
时,您重新应用以前的数据库状态通过查看转储文件。
但是,对我来说似乎有点hacker,并且可能很难正确处理所有情况:
重新定级, merge , cherry-pick 等。
在我看来,处理迁移冲突时比较容易。