我正在使用Django 1.5b1和南部迁移,生活一般都很棒。我有一些架构更新,用于创建我的数据库,其中包括User表。然后我为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放弃了DB错误。不幸的是,我无法在我的夹具中将我的模型指定为orm['ff.User']
,这似乎是南方的做事方式。
我应该如何使用南方正确加载灯具,以便一旦这些灯具所针对的模型被修改后它们不会断开?
答案 0 :(得分:5)
我找到了一个可以完成这项工作的Django代码段!
https://djangosnippets.org/snippets/2897/
它根据夹具中冻结的模型加载数据,而不是应用程序代码中的实际模型定义!适合我。
答案 1 :(得分: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()
答案 2 :(得分:0)
这也是我使用灯具的一个令人沮丧的部分。我的解决方案是制作一些辅助工具。通过从数据库中采样数据来创建灯具,并在灯具中包含南移民历史。
还有一个工具可以将南迁移历史记录添加到现有设备中。
第三个工具在修改此夹具时检出提交,加载夹具,然后检出最近的提交并执行向南迁移并将迁移的数据库转储回夹具。这是在一个单独的数据库中完成的,因此您的默认数据库不会被踩踏。
前两个可以被认为是beta代码,第三个可以视为可用的alpha,但它们对我来说已经非常有用了。
很想从别人那里得到一些反馈: git@github.com:JivanAmara / django_fixture_tools.git 目前,它仅支持使用git作为RCS的项目。
答案 3 :(得分:0)
我发现的最优雅的解决方案是here,您的应用模型的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)
来调用它。
答案 4 :(得分:-1)
一般来说,South使用forwards()
和backwards()
函数处理迁移。在你的情况下,你应该:
在第二种情况下,在迁移添加(或者,在您的情况下,删除)列之前,您应该执行将与此类似地显式加载灯具的迁移(docs):
def forwards(self, orm):
from django.core.management import call_command
call_command("loaddata", "create_users.json")
我相信这是完成所需工作的最简单方法。另外,请确保在执行较旧的迁移之前,不要尝试使用新结构导入数据等一些简单的错误。
答案 5 :(得分:-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的好处,例如灯具需要。