4

我正在使用 Django 1.5b1 和南迁移,生活一般都很棒。我有一些创建我的数据库的架构更新,其中包括一个用户表。ff.User然后我为(我的自定义用户模型)加载一个夹具:

def forwards(self, orm):
        from django.core.management import call_command
        fixture_path = "/absolute/path/to/my/fixture/load_initial_users.json"
        call_command("loaddata", fixture_path)

在我向我的ff.User模型中添加另一个字段之前,一切都运行良好,在迁移线的更下方。我的夹具负载现在中断:

DatabaseError: Problem installing fixture 'C:\<redacted>create_users.json':
Could not load ff.User(pk=1): (1054, "Unknown column 'timezone_id' in 'field list'")

时区是我添加到我的用户模型中的字段 (ForeignKey)。

ff.User 与数据库中的不同,因此 Django ORM 放弃了数据库错误。不幸的是,我无法在我的夹具中将我的模型指定为orm['ff.User'],这似乎是南方的做事方式。

我应该如何使用南正确加载固定装置,以便在修改这些固定装置的模型后它们不会损坏?

4

6 回答 6

5

我找到了一个可以完成这项工作的 Django 片段!

https://djangosnippets.org/snippets/2897/

它根据固定在夹具中的模型而不是应用程序代码中的实际模型定义来加载数据!非常适合我。

于 2014-03-24T12:23:26.653 回答
1

我提出了一个您可能也会感兴趣的解决方案:

https://stackoverflow.com/a/21631815/797941

基本上,这就是我加载我的夹具的方式:

from south.v2 import DataMigration
import json

class Migration(DataMigration):

    def forwards(self, orm):
        json_data=open("path/to/your/fixture.json")
        items = json.load(json_data)
        for item in items:
            # Be carefull, this lazy line won't resolve foreign keys
            obj = orm[item["model"]](**item["fields"])
            obj.save()

        json_data.close()
于 2014-02-07T15:44:07.600 回答
0

这对我来说也是使用固定装置的一个令人沮丧的部分。我的解决方案是制作一些辅助工具。一种通过从数据库中采样数据来创建夹具并在夹具中包含南迁移历史的方法。

还有一个工具可以将南迁移历史添加到现有的装置中。

第三个工具在修改此夹具时检查提交,加载夹具,然后检查最近的提交并进行南迁移并将迁移的数据库转储回夹具。这是在一个单独的数据库中完成的,因此您的默认数据库不会被踩到。

前两个可以被认为是 beta 代码,第三个可以被视为可用的 alpha,但它们已经对我很有帮助。

希望从其他人那里得到一些反馈:git@github.com:JivanAmara/django_fixture_tools.git 目前,它只支持使用 git 作为 RCS 的项目。

于 2014-06-12T19:40:32.350 回答
0

我发现的最优雅的解决方案是在这里,您的应用程序模型的get_model功能被切换为从提供的 orm 提供模型。然后在应用夹具后将其设置回来。

from django.db import models
from django.core.management import call_command

def load_fixture(file_name, orm):
    original_get_model = models.get_model

    def get_model_southern_style(*args):
        try:
            return orm['.'.join(args)]
        except:
            return original_get_model(*args)

    models.get_model = get_model_southern_style
    call_command('loaddata', file_name)
    models.get_model = original_get_model

load_fixture('my_fixture.json', orm)你从你的转发定义中调用它。

于 2015-02-27T20:51:52.570 回答
-1

forwards()通常 South 使用和backwards()函数处理迁移。在您的情况下,您应该:

  • 更改夹具以包含正确的数据,或
  • 在迁移之前导入夹具会破坏它(或在同一迁移中,但在更改架构之前),

在第二种情况下,在迁移添加(或在您的情况下,删除)列之前,您应该执行将显式加载固定装置的迁移,类似于此(文档):

def forwards(self, orm):
    from django.core.management import call_command
    call_command("loaddata", "create_users.json")

我相信这是完成您需要的最简单的方法。还要确保在应用旧迁移之前不要犯一些简单的错误,例如尝试使用新结构导入数据。

于 2012-12-11T18:06:09.557 回答
-1

阅读以下两篇文章帮助我想出了一个解决方案:

http://andrewingram.net/2012/dec/common-pitfalls-django-south/#be-careful-with-fixtures

http://news.ycombinator.com/item?id=4872596

具体来说,我重写了我的数据迁移以使用“dumpscript”的输出

我需要稍微修改生成的脚本以与南一起使用。而不是做

from ff.models import User

我愿意

User = orm['ff.User']

这完全像我想要的那样工作。此外,它还具有不硬编码 ID 的好处,就像固定装置需要的那样。

于 2012-12-12T12:07:20.780 回答