Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python django迁移-具有多个开发分支的工作流_Python_Django_Git_Migration - Fatal编程技术网

Python django迁移-具有多个开发分支的工作流

Python django迁移-具有多个开发分支的工作流,python,django,git,migration,Python,Django,Git,Migration,我很好奇其他django开发人员如何通过迁移管理多个代码分支(例如git) 我的问题如下: -我们在git中有多个特性分支,其中一些具有django迁移(其中一些更改字段,或者完全删除字段) -当我切换分支(使用git checkout some_other_branch)时,数据库并不总是反映新代码,因此我会遇到“随机”错误,其中不再存在db表列,等等 现在,我只是删除数据库并重新创建它,但这意味着我必须重新创建一堆虚拟数据才能重新开始工作。我可以使用fixture,但它需要跟踪数据的去向,这

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

我的问题如下: -我们在git中有多个特性分支,其中一些具有django迁移(其中一些更改字段,或者完全删除字段) -当我切换分支(使用
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
    )。确保没有错误,但是我应该通过该操作删除的表/字段仍然在我的数据库中,并且要求我手动删除每个表/字段!为什么这会间歇性地起作用?