Django:迁移错误中的loaddata

laj*_*rre 5 python django database-migration

自从使用Django迁移(不是南方)并在其中使用loaddata for fixture以来,我发生了一些令人讨厌的事情.

这是一个重现我的问题的简单方法:

  • 创建一个Testmodel包含1个字段的新模型field1(CharField或其他)
  • 创建一个关联的迁移(比如说0001)makemigrations
  • 运行迁移
  • 并在新表中添加一些数据
  • 将数据转储到夹具中 testmodel.json
  • 使用以下命令创建迁移call_command('loaddata', 'testmodel.json'):迁移0002
  • 在模型中添加一些新字段: field2
  • 创建关联的迁移(0003)

现在,提交,并将您的数据库置于更改之前的状态:./manage.py migrate myapp zero.所以你和你的队友处于同样的状态,但还没有得到你的改变.

如果您尝试./manage.py migrate再次运行,您将获得ProgrammingError迁移0002,称"列field2不存在".

这似乎是因为loaddata正在调查你的模型(已经有了field2),而不仅仅是将数据包应用于数据库.

在团队中工作时,可能会发生多种情况,也会导致测试运行器失败.

我弄错了吗?这是一个错误吗?应该做些什么呢?

-

我正在使用django 1.7

Gwy*_*idD 10

loaddata命令只会调用序列化程序.序列化程序将处理来自models.py文件的模型状态,而不是当前的迁移,但是没有什么可以欺骗默认的序列化程序.

首先,您不希望使用该序列化程序,call_command而是直接使用该序列化程序:

from django.core import serializers

def load_fixture(apps, schema_editor):
    fixture_file = '/full/path/to/testmodel.json'
    fixture = open(fixture_file)
    objects = serializers.deserialize('json', fixture, ignorenonexistent=True)
    for obj in objects:
        obj.save()
    fixture.close()
Run Code Online (Sandbox Code Playgroud)

其次,序列化器使用的monkey-patch apps注册表:

from django.core import serializers

def load_fixture(apps, schema_editor):
    original_apps = serializers.python.apps
    serializers.python.apps = apps
    fixture_file = '/full/path/to/testmodel.json'
    fixture = open(fixture_file)
    objects = serializers.deserialize('json', fixture, ignorenonexistent=True)
    for obj in objects:
        obj.save()
    fixture.close()
    serializers.python.apps = original_apps
Run Code Online (Sandbox Code Playgroud)

现在,序列化程序将使用模型状态apps而不是默认状态,整个迁移过程将成功.