11

我最近在导入比我当前模型架构更旧的数据时遇到了一个问题。我使用并导致错误的流程:

  • 使用 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 行,在执行中返回 self.cursor.execute(query, args) DatabaseError: 关系 "localization_province" 的列 "mpoly" 不存在 LINE 1: ...e" ("id", "name", "slug" , "mpoly") V...

  • 评论在 0003 之前完成的 models.py 中的更改,让一切正常

如果我想加载数据,有什么方法可以避免在向后迁移后使用模型?

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

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

4

3 回答 3

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 及更高版本。

于 2011-05-06T02:45:42.907 回答
3

我发现最好使我拥有的所有固定装置与当前版本的代码保持一致。因此,在创建迁移 0003 时,您将执行数据迁移和新dumpdata的替换夹具 0002。创建数据迁移时,请确保您同时执行正向和反向操作,这样当您迁移回0002.

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

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

另见南方关于固定装置的文档评论

这是一个想法,受上面那个链接的启发:“最好的办法是编写一个新的迁移来加载夹具”。从迁移而不是loaddata. 您仍然需要创建数据迁移并使用该orm对象手动加载数据。您可以使用 django 的序列化函数,这正是loaddata 的作用。

关于为什么loaddata使用模型版本而不是数据库版本:loaddata是一个django 管理命令,不知道南在做什么。因此,它需要保持与数据库无关并使用 django 的 ORM。如果您需要做一些更具体的事情,您总是可以编写自己的管理命令- 可能会提取一些 south 的 orm 版本控制,或者执行直接从数据库读取模式的数据库特定 loaddata。我认为上一段中的解决方案将少很多工作。

于 2011-03-29T17:41:33.303 回答
2

迟到了这个讨论,但希望这会有所帮助。实际上,您可以采取两种方法:

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

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

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

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

于 2012-12-05T02:45:53.913 回答