django在向后迁移/ loaddata之后从fixture中加载数据是使用模型模式而不是数据库模式

时间:2011-03-29 13:02:02

标签: django django-south

我在导入旧数据时遇到问题,而不是我当前的模型架构。我使用的流程导致错误:

  • dumpdata with python manage.py dumpdata - > 0002
  • 对模型进行一些修改
  • 使用python manage.py schemamigration app_name生成迁移--auto - > 0003
  • 运行迁移
  • 玩数据库
  • 迁移到0002
  • loaddata生成SQL,其中我有当前(迁移0003)字段,并导致loaddata进程失败(mpoly已添加字段)
  File "/usr/local/lib/python2.6/dist-packages/django/db/backends/postgresql_psycopg2/base.py",
     

第44行,执行中           return self.cursor.execute(query,args)       DatabaseError:关系“localization_province”的列“mpoly”   不存在       第1行:......“”(“id”,“name”,“slug”,“mpoly”)V ...

  • 评论在0003之前完成的models.py中的更改,使所有工作正常

如果我想加载数据,是否有办法避免在向后迁移后使用模型?

也许我错过了一些非常明显的东西......

PS:我使用South 7.3,Django 1.2.3和PostgreSQL 8.4作为数据库后端。

3 个答案:

答案 0 :(得分:10)

Alex Vidal提出了一个很好的快速解决方案,当它咬我们的工作。它需要Gary Bernhardt的Dingus库。一旦我们有时间,我们就会将Dingus依赖关系分解出来并向South提交拉取请求,但是如果你现在处于绑定状态,这可能会让你失去它:

from dingus import patch


def loaddata(orm, fixture_name):
    _get_model = lambda model_identifier: orm[model_identifier]

    with patch('django.core.serializers.python._get_model', _get_model):
        from django.core.management import call_command
        call_command("loaddata", fixture_name)

用法:

from apps.common.utils import loaddata


class Migration(DataMigration):
    def forwards(self, orm):
        loaddata(orm, "initial_fjords.json")

到目前为止,我们仅在Django 1.3中进行了测试。 编辑:我查看了Django的_get_model历史记录,这应该适用于Django 0.95及以上版本。

答案 1 :(得分:3)

我发现最好保留我所拥有的任何灯具与当前版本的代码一致。因此,在创建迁移0003时,您执行data migration和新dumpdata,替换fixture 0002.当您创建数据迁移时,请确保您同时执行前向和后退,这样您最终将会迁移回0002时的正确数据。

执行数据迁移时,请确保通过orm对象访问所有模型,否则最终会出现类似于您已经遇到的错误。

如果由于某种原因想要使用旧数据(版本0002)实际运行django代码,那么您的模型需要匹配您的数据库。这意味着使用您正在使用的任何代码版本(git,hg,svn ...)检出适当版本的代码。如果你试图“及时”解决问题,你可能也想在那时进行分支。

另见south's documentation comments on fixtures

这是一个受上述链接启发的想法:“最好的办法是编写一个新的迁移来加载夹具”。如何从迁移中加载您的夹具(您已经拥有),而不是loaddata。您仍然需要创建数据迁移并使用orm对象手动加载数据。您可以使用django的serialization functions,这正是loaddata does

关于loaddata使用模型版本而不是数据库版本的原因:loaddatadjango management command,不知道南方正在做什么。因此,它需要保持数据库不可知并使用django的ORM。如果您需要做一些更具体的事情,可以随时write your own management command - 可能会删除某些南方版本的版本,或者执行直接从数据库中读取架构的数据库特定的加载数据。我认为前一段中的解决方案将会少得多。

答案 2 :(得分:2)

讨论的后期,但希望这有用。你真的可以采取两种方法:

  • 在迁移的早期加载数据,然后使用数据 迁移以在您进行架构迁移时进行更改。这样做的好处是您可以随时测试数据迁移。

  • 将数据加载为夹具,它将始终使用您当前的模型 因此要求您保持最新的灯具。

除了上述方法之外,您还可以使用dumpscript(作为django-command-extensions的一部分提供)来加载数据,以便在python中转储您的fixture。从那里你需要编辑夹具以使用迁移中可用的ORM,而不是你的Django模型。如果您没有太多数据,这通常最有用。

请参阅:http://south.aeracode.org/attachment/ticket/1010/fixtures.diff