django迁移-具有多个开发分支的工作流 [英] django migrations - workflow with multiple dev branches

查看:113
本文介绍了django迁移-具有多个开发分支的工作流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm curious how other django developers manage multiple code branches (in git for instance) with migrations.

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

My problem is as follows: - we have multiple feature branches in git, some of them with django migrations (some of them altering fields, or removing them altogether) - when I switch branches (with git checkout some_other_branch) the database does not reflect always the new code, so I run into "random" errors, where a db table column does not exist anymore, etc...

现在,我只是删除数据库并重新创建它,但这意味着我必须重新创建一堆虚拟数据才能重新开始工作.我可以使用固定装置,但是它需要跟踪数据将流向何处,这有点麻烦.

Right now, I simply drop the db and recreate it, but it means I have to recreate a bunch of dummy data to restart work. I can use fixtures, but it requires keeping track of what data goes where, it's a bit of a hassle.

是否有一种良好/干净的方式来处理此用例?我在想post-checkout git hook脚本可以运行必要的迁移,但我什至不知道迁移回滚是否完全可能.

Is there a good/clean way of dealing with this use-case? I'm thinking a post-checkout git hook script could run the necessary migrations, but I don't even know if migration rollbacks are at all possible.

推荐答案

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

Migrations rollback are possible and usually handled automatically by django.

考虑以下模型:

class MyModel(models.Model):
    pass

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

If you run python manage.py makemigrations myapp, it will generate the initial migration script. You can then run python manage.py migrate myapp 0001 to apply this initial migration.

如果之后将字段添加到模型中,则:

If after that you add a field to your model:

class MyModel(models.Model):    
    my_field = models.CharField()

然后重新生成一个新的迁移并应用它,您仍然可以返回到初始状态.赶紧跑 python manage.py migrate myapp 0001和ORM将向后,删除新字段.

Then regenerate a new migration, and apply it, you can still go back to the initial state. Just run python manage.py migrate myapp 0001 and the ORM will go backward, removing the new field.

在处理数据迁移时,这更加棘手,因为您必须编写前进和后退代码. 考虑到通过python manage.py makemigrations myapp --empty创建的空迁移, 你最终会得到类似的东西:

It's more tricky when you deal with data migrations, because you have to write the forward and backward code. Considering an empty migration created via python manage.py makemigrations myapp --empty, you'll end up with something like:

# -*- 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"),通常必须编写后退步骤.

For pure data-loading migrations, you usually don't need the backward migration. But when you alter the schema and update existing rows,
(like converting all values in a column to slug), you'll generally have to write the backward step.

在我们的团队中,我们尽量避免同时使用相同的模型,以免发生碰撞. 如果无法实现,并且创建了两个具有相同编号(例如0002)的迁移, 您仍然可以重命名其中之一来更改应用它们的顺序(也请记住要进行更新 迁移类上的dependencies属性添加到您的新订单).

In our team, we try to avoid working on the same models at the same time to avoid collision. If it is not possible, and two migration with the same number (e.g 0002) are created, you can still rename one of them to change the order in will they will be applied (also remember to update the dependencies attribute on the migration class to your new order).

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

If you end up working on the same model fields at the same time in different features, you'll still be in trouble, but it may means these features are related and should be handled together in a single branch.

对于git-hooks部分,可能有可能写点东西,假设您在分支mybranch 并想查看另一个功能分支myfeature:

For the git-hooks part, it's probably possible to write something, Assuming your are on branch mybranch and want to check out another feature branch myfeature:

  1. 在切换之前,将当前已应用的迁移列表转储到 临时文件mybranch_database_state.txt
  2. 然后,您应用myfeature分支迁移(如果有)
  3. 然后,当再次检查mybranch时,您将重新应用以前的数据库状态 通过查看转储文件.
  1. Just before switching, you dump the list of currently applied migrations into a temporary file mybranch_database_state.txt
  2. Then, you apply myfeature branch migrations, if any
  3. Then, when checking back mybranch, you reapply your previous database state by looking to the dump file.

但是,对我来说似乎有点黑,可能很难正确处理所有情况: 重新定级,合并,挑选樱桃等.

However, it seems a bit hackish to me, and it would probably be really difficult to handle properly all scenarios: rebasing, merging, cherry-picking, etc.

在我看来,处理迁移冲突很容易.

Handling the migrations conflicts when they occurs seems easier to me.

这篇关于django迁移-具有多个开发分支的工作流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆