我正在使用Django 1.6,我使用South来处理迁移。
在我的大多数应用程序中,我曾经有initial_data.json
个文件。我将它们转换为加载迁移而不是Django自动加载(正如文档中推荐的那样)
当我遇到一个奇怪的行为/错误,根据模型代码而不是迁移状态完成加载装置时,我使用的是南方版本0.8.2。我看到最新版本(0.8.4)已经添加了一些与loaddata
相关的错误修复,所以我升级到它。
现在我在加载灯具的所有迁移中收到以下错误:
UserWarning: No fixture named 'X' found.
当我使用Django的loaddata
时,它运行正常。关于如何解决这个问题的任何想法?
答案 0 :(得分:5)
South只是修补syncdb以跳过具有迁移的模型的夹具加载,并且在运行应用程序的最终迁移后实际加载它们。
加载initial_data并不需要您实际执行某些操作,而是将灯具放在the correct place as explained in Django's documentation中。
引用文档:
默认情况下,Django会查看每个应用内的fixtures目录 灯具。您可以将FIXTURE_DIRS设置设置为附加列表 Django应该看的目录。
这意味着如果您有一个名为“myapp”的应用程序,您将在其中创建一个“fixtures”目录并将json放在那里,例如:myproject/myapp/fixtures
。
Django 1.7 introduced built-in migrations。它们的界面类似于南方;用于创建迁移的管理命令makemigrations
,运行它们migrate
以及其他。
但是,initial_data
灯具不再在syncdb运行时自动加载;除非它是现有的应用程序,并且没有迁移。这是mentioned in the release notes。
文档现在建议创建一个datamigration
来处理夹具加载。幸运的是,这很容易做到,这就是我通常的做法:
$ python manage.py makemigrations --empty myapp
如果您只进行了初始迁移,最终会得到这些文件(请注意,为了清楚起见,我重命名了迁移0002):
myapp/
├── __init__.py
├── fixtures
│ └── my_initial_data.json
└── migrations
├── 0001_initial.py
├── 0002_load_fixture.py
└── __init__.py
0002_load_fixture.py
的代码以运行loaddata # -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
from django.core.management import call_command
def load_my_initial_data(apps, schema_editor):
call_command("loaddata", "my_initial_data.json")
class Migration(migrations.Migration):
dependencies = [
('myapp', '0001_initial'),
]
operations = [
migrations.RunPython(load_my_initial_data),
]
答案 1 :(得分:2)
当文件名不包含'.json'扩展名时,也会发生此错误。
为了从当前工作目录加载一个灯具,它必须以'.json'结尾。
答案 2 :(得分:0)
为什么不从迁移中运行load data命令呢?
import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
class Migration(DataMigration):
def forwards(self, orm):
from django.core.management import call_command
call_command("loaddata", "my_fixture.json")
答案 3 :(得分:0)
如果您仍然收到错误:
找不到名为'X'的夹具
尝试使用json文件的路径,因为manage.py可能没有从项目目录运行(甚至可能从根目录运行)。尝试这样的事情:
import os
app_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))
json_path = os.path.join(app_path, 'fixtures', 'my_fixture.json')
call_command("loaddata", json_path)