Неужели Джанго Грок YML? Джанго не загружается светильников YML-файл (YML-это не известно сериализации)
Я успешно создал свой первый проект django.
У меня есть два приложения в моем проекте foo и foobar.
Я создал папку с именем "светильники" в каждой из папок приложения. Я не указал каталог светильников в своих настройках.yml, так что (согласно docs), django должен искать в моей папке {app} / fixtures.
В папке {app} / fixtures у меня есть несколько файлов YML. Я разделил исходные данные для различных модулей на отдельные YML файлы, убедившись, что нет перекрестных зависимостей файлов (то есть все связанные модели находятся в одном файле YML и предки встречаются в файле до моделей, которые их используют).
Однако, когда я run./manage.py syncdb после успешного создания объектов БД появилось следующее сообщение:
Не найдено приспособлений
Затем я попытался вручную загрузить светильники с помощью команды loaddata:
./manage.py loaddata 0100_foobar.yml
Problem installing fixture '0100_foobar': yml is not a known serialization
Является ли документация, приведенная в ссылке выше, неправильной?, или нужно ли мне установить модуль для того, чтобы django мог grok YML?
Кстати, файлы YML разбираются правильно и были проверены на корректность (я успешно использовал их в другом проекте) - так что это не проблема
[Edit]
Я установил PyYaml и переименовал свои файлы светильников в соответствии с инструкциями Маноя. Я могу пройти немного дальше по линии, но я все еще сталкиваюсь с проблемами (кстати, я использую PyYaml 3.0.9).
Вот модель в моем project ORM (то есть {app}/model.py):
class Currency(models.Model):
short_name = models.CharField(max_length=3, db_index=True, unique=True, null=False) # ISO Code
long_name = models.CharField(max_length=64, db_index=True, unique=True, null=False)
spot_settle = models.IntegerField(null=False, default=0)
rounding = models.IntegerField(null=False, default=2)
Вот файл YAML, который я импортирую:
Currency:
currency_aud : { short_name: AUD , long_name: Australia - Dollars , spot_settle: 0, rounding: 2 }
currency_cad : { short_name: CAD , long_name: Canada - Dollars , spot_settle: 0, rounding: 2 }
currency_eur : { short_name: EUR , long_name: Euro Member Countries - Euro , spot_settle: 0, rounding: 2 }
currency_gbp : { short_name: GBP , long_name: United Kingdom - Pounds , spot_settle: 0, rounding: 2 }
currency_jpy : { short_name: JPY , long_name: Japan - Yen , spot_settle: 0, rounding: 2 }
currency_usd : { short_name: USD , long_name: United States Of America - Dollars , spot_settle: 0, rounding: 2 }
currency_zar : { short_name: ZAR , long_name: South Africa - Rand, spot_settle: 0, rounding: 2 }
currency_hkd : { short_name: HKD , long_name: Hong Kong Dollar, spot_settle: 0, rounding: 2 }
currency_nzd : { short_name: NZD , long_name: New Zealand Dollar, spot_settle: 0, rounding: 2 }
currency_sgd : { short_name: SGD , long_name: Singapore Dollar, spot_settle: 0, rounding: 2 }
currency_dkk : { short_name: DKK , long_name: Danish Krone, spot_settle: 0, rounding: 2 }
currency_sek : { short_name: SEK , long_name: Swedish Krona, spot_settle: 0, rounding: 2 }
currency_chf : { short_name: CHF , long_name: Swiss Franc, spot_settle: 0, rounding: 2 }
Вот трассировка стека, когда я выполняю. /manage.py loaddata myapp / светильники / валюты.ямл
me@somebox:~/work/demo/myproj$ ./manage.py loaddata reference/fixtures/0100_currency.yaml
Installing yaml fixture 'reference/fixtures/0100_currency' from absolute path.
Problem installing fixture 'reference/fixtures/0100_currency.yaml': Traceback (most recent call last):
File "/usr/local/lib/python2.6/dist-packages/django/core/management/commands/loaddata.py", line 165, in handle
for obj in objects:
File "/usr/local/lib/python2.6/dist-packages/django/core/serializers/pyyaml.py", line 57, in Deserializer
for obj in PythonDeserializer(yaml.load(stream), **options):
File "/usr/local/lib/python2.6/dist-packages/django/core/serializers/python.py", line 84, in Deserializer
Model = _get_model(d["model"])
TypeError: string indices must be integers, not str
2 ответа:
Я попытался воспроизвести вашу проблему в одном из своих проектов. По-видимому
Местные тесты показали, что моя гипотеза верна.loaddata
ожидает, что расширение файла в соответствии с форматом сериализации. В вашем случае вам следует переименовать файл в0100_foobar.yaml
(Обратите внимание на новое расширение).PS : для сериализации YAML требуется библиотека
PyYAML
. Если вы еще не сделали этого, установите PyYAML.Обновить
Я скопировал ОП модель для одного из моих проектов. Когда я попытался загрузить образец YAML, заданный OP as-is, я получил ту же ошибку.
После этого я добавил некоторые данные с помощью приложения admin и использовал
django.core.serializers.serialize
для дампа данных в формате YAML.Результат, который я получил, значительно отличался от того, что опубликовал ОП. Увидеть ниже. Я добавил три экземпляра для модели, и они появляются.from django.core.serializers import serialize from app.models import Currency print serializers.serialize("yaml", Currency.objects.all())
Я смог загрузить эти данные обратно без каких-либо проблем.- fields: {long_name: Australia - Dollars, rounding: 2, short_name: AUD, spot_settle: 0} model: app.currency pk: 1 - fields: {long_name: Canada - Dollars, rounding: 2, short_name: CAD, spot_settle: 0} model: app.currency pk: 2 - fields: {long_name: Euro Member Countries - Euro, rounding: 2, short_name: EUR, spot_settle: 0} model: app.currency pk: 3
Учитывая выше я подозреваю, что в файле YAML OP что-то не так. @skyeagle, вы можете попробовать сбросить существующие данные и затем попробовать загрузить дамп обратно?
Для тех, кто, подобно мне, просто упрям и очень, очень хочет использовать файлы с расширением
.yml
, Вы можете зарегистрировать сериализатор при запуске, чтобыloaddata
распознал файл fixture:from django.apps import AppConfig from django.core.serializers import register_serializer class MyAppConfig(AppConfig): name = 'my_app_name' label = 'my_app_label' verbose_name = 'this is my really cool app' def ready(self): register_serializer('yml', 'django.core.serializers.pyyaml')
Вызов
register_serializer
зарегистрируетyml
как распознанное расширение.