Python django迁移-具有多个开发分支的工作流
我很好奇其他django开发人员如何通过迁移管理多个代码分支(例如git) 我的问题如下: -我们在git中有多个特性分支,其中一些具有django迁移(其中一些更改字段,或者完全删除字段) -当我切换分支(使用Python django迁移-具有多个开发分支的工作流,python,django,git,migration,Python,Django,Git,Migration,我很好奇其他django开发人员如何通过迁移管理多个代码分支(例如git) 我的问题如下: -我们在git中有多个特性分支,其中一些具有django迁移(其中一些更改字段,或者完全删除字段) -当我切换分支(使用git checkout some_other_branch)时,数据库并不总是反映新代码,因此我会遇到“随机”错误,其中不再存在db表列,等等 现在,我只是删除数据库并重新创建它,但这意味着我必须重新创建一堆虚拟数据才能重新开始工作。我可以使用fixture,但它需要跟踪数据的去向,这
git checkout some_other_branch
)时,数据库并不总是反映新代码,因此我会遇到“随机”错误,其中不再存在db表列,等等
现在,我只是删除数据库并重新创建它,但这意味着我必须重新创建一堆虚拟数据才能重新开始工作。我可以使用fixture,但它需要跟踪数据的去向,这有点麻烦
是否有一个好的/干净的方法来处理这个用例?我认为签出后的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迁移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)的迁移,
您仍然可以重命名其中一个,以更改应用它们的顺序(也请记住更新)
迁移类上的依赖项
属性(新订单)
如果在不同的要素中同时处理相同的模型字段,
您仍然会遇到麻烦,但这可能意味着这些功能是相关的,应该加以处理
一起在一个分支中
对于git钩子部分,假设您在分支mybranch
并想查看另一个功能分支myfeature
:
在切换之前,将当前应用的迁移列表转储到
一个临时文件mybranch\u database\u state.txt
然后,应用分支迁移(如果有的话)
然后,当检查回mybranch
时,重新应用以前的数据库状态
通过查看转储文件
然而,对我来说,这似乎有点黑客化,并且可能真的很难正确处理所有场景:
重定基址、合并、樱桃采摘等
在迁移冲突发生时处理它们对我来说似乎更容易。我没有一个很好的解决方案,但我感到痛苦
签出后挂钩将太迟。如果您在分支A上签出分支B,并且B的迁移比A少,则回滚信息仅在A中,需要在签出之前运行
当我在几个提交之间跳来跳去试图找到bug的来源时,我遇到了这个问题。我们的数据库(即使在开发中)很大,所以删除和重新创建是不现实的
我正在想象git checkout的包装:
记录每个已安装应用的最新迁移
查看请求的分支并在那里记录最新的迁移
对于#1中的迁移比#2中的迁移要快的应用程序,请迁移回#2中迁移最高的应用程序
查看新的分支
对于#2中的迁移领先于#1的每个应用程序,请向前迁移
一个简单的编程问题 对于简单的更改,我依赖于迁移回滚,正如所讨论的
但是,如果我知道某个功能分支将涉及高度侵入性的数据库更改,或者如果它将涉及大量数据迁移,我希望在启动新分支后立即创建本地(或远程开发人员)数据库的克隆。这可能并不总是很方便,但特别是对于使用sqlite的本地开发来说,复制文件(不受源代码控制)只是一件事
新分支上的第一次提交将更新my Django(local/dev)以使用克隆的数据库。这样,当我切换分支时,会自动选择正确的数据库。不需要担心回滚模式更改、丢失数据等。不需要复杂的东西
功能分支完全合并后,可以删除克隆的数据库。我认为@eliot berriot涵盖了大多数情况。事实上,我是受这个问题的启发,写了这篇文章,提出了一个建议:。并使用签出后git钩子方案启动此库:。您认为呢?这个答案通常是有效的,但我似乎有很多情况下,简单地回滚到特定的/早期的迁移并不能撤消更改(例如,python manage.py migrate myapp 0001
)。确保没有错误,但是我应该通过该操作删除的表/字段仍然在我的数据库中,并且要求我手动删除每个表/字段!为什么这会间歇性地起作用?