django迁移 - 具有多个dev分支的工作流

Lau*_*t S 32 python migration git django

我很好奇其他django开发人员如何使用迁移管理多个代码分支(例如git).

我的问题如下: - 我们在git中有多个功能分支,其中一些具有django迁移(其中一些改变字段,或者完全删除它们) - 当我切换分支(带git checkout some_other_branch)时,数据库并不总是反映新代码,所以我遇到"随机"错误,其中db表列不再存在,等等...

现在,我只是删除数据库并重新创建它,但这意味着我必须重新创建一堆虚拟数据才能重新开始工作.我可以使用灯具,但它需要跟踪哪些数据在哪里,这有点麻烦.

处理这个用例有没有好的/干净的方法?我认为post-checkoutgit hook脚本可以运行必要的迁移,但我甚至不知道迁移回滚是否完全可行.

Eli*_*iot 18

迁移回滚是可能的,通常由django自动处理.

考虑以下型号:

class MyModel(models.Model):
    pass
Run Code Online (Sandbox Code Playgroud)

如果运行python manage.py makemigrations myapp,它将生成初始迁移脚本.然后,您可以运行python manage.py migrate myapp 0001以应用此初始迁移.

如果之后您在模型中添加了一个字段:

class MyModel(models.Model):    
    my_field = models.CharField()
Run Code Online (Sandbox Code Playgroud)

然后重新生成一个新的迁移并应用它,您仍然可以返回到初始状态.只需运行 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),
    ]
Run Code Online (Sandbox Code Playgroud)

对于纯数据加载迁移,通常不需要向后迁移.但是当您更改架构并更新现有行时
(例如将列中的所有值转换为slug),您通常必须编写后退步骤.

在我们的团队中,我们尽量避免同时使用相同的模型以避免碰撞.如果不可能,并且创建了两个具有相同编号的迁移(例如0002),您仍然可以重命名其中一个以更改它们将被应用的顺序(还记得dependencies将迁移类的属性更新为您的新命令).

如果您最终在不同的功能中同时处理相同的模型字段,您仍然会遇到麻烦,但这可能意味着这些功能是相关的,应该在一个分支中一起处理.

对于git-hooks部分,它可能会写一些东西,假设你在分支上mybranch 并想要查看另一个功能分支myfeature:

  1. 在切换之前,您将当前应用的迁移列表转储到临时文件中 mybranch_database_state.txt
  2. 然后,您应用myfeature分支迁移(如果有)
  3. 然后,在检查时mybranch,通过查看转储文件重新应用以前的数据库状态.

然而,对我来说似乎有些苛刻,并且可能很难正确处理所有场景:变基,合并,挑选等等.

处理迁移发生时的冲突对我来说似乎更容易.


Pau*_*sex 6

我没有很好的解决方案,但我感到痛苦。

结帐后挂钩将为时已晚。如果您在分支机构A上并且签出分支机构B,并且B的迁移少于A,则回滚信息仅在A中,并且需要签出之前运行。

在尝试查找错误来源的几次提交之间跳转时,我遇到了这个问题。我们的数据库(即使在开发阶段)也是巨大的,因此删除和重新创建是不切实际的。

我在想一个git-checkout的包装器:

  1. 记录每个INSTALLED_APPS的最新迁移
  2. 在请求的分支中查找并记录那里的最新迁移
  3. 对于#1迁移比#2迁移更远的每个应用,请迁移回#2的最高迁移
  4. 签出新分支
  5. 对于#2迁移领先于#1的每个应用,请向前迁移

编程很简单!