首页 文章

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

提问于
浏览
11

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

  • dumpdata与python manage.py dumpdata - > 0002

  • 对模型进行一些修改

  • 使用python manage.py schemamigration app_name --auto - > 0003生成迁移

  • 运行迁移

  • 玩数据库

  • 迁移到0002

  • loaddata生成SQL,其中我有当前(迁移0003)字段,并导致loaddata进程失败(mpoly是添加字段)

文件“/usr/local/lib/python2.6/dist-packages/django/db/backends/postgresql_psycopg2/base.py”,
第44行,在执行中返回self.cursor.execute(query,args)DatabaseError:关系“localization_province”的列“mpoly”不存在第1行:... e“(”id“,”name“,”slug“ ,“mpoly”)V ...

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

Is there any way to avoid playing with models after backward migration if I want to loaddata?

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

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

3 回答

  • 10

    Alex Vidal提出了一个很好的快速解决方案,当它咬我们的工作 . 它需要Gary Bernhardt的Dingus库 . 一旦我们有时间,我们现在就在绑定中,这可能会让你失去它:

    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中进行了测试 . Edit :我检查了Django的 _get_model 历史,这应该适用于Django 0.95及以上 .

  • 2

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

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

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

    另见south's documentation comments on fixtures

    这是一个想法,受上述链接的启发:"the best thing to do is to write a new migration to load the fixture in" . 如何从迁移中加载您的夹具(您已经拥有),而不是 loaddata . 您仍然需要创建数据迁移并使用 orm 对象手动加载数据 . 你可以使用django的serialization functions,这正是 loaddata does .

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

  • 3

    在讨论的后期,但希望这是有帮助的 . 你真的可以采取两种方法:

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

    • 将数据作为夹具加载,它将始终使用您当前的模型,因此需要您使夹具保持最新状态 .

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

    见:http://south.aeracode.org/attachment/ticket/1010/fixtures.diff

相关问题