I have successfully created my first django project.
I have two apps in my project foo and foobar.
I have created a folder named 'fixtures' in each of the app folders. I have NOT specified a fixtures directory in my settings.yml, so (according to the docs), django should be looking in my {app}/fixtures folder.
In the {app}/fixtures folder, I have several YML files. I have split the initial data for the various modules into separate YML files, making sure there are no cross file dependencies (i.e. all related models are in the same YML file and ancestors occur in the file before models that use them).
However, when I run./manage.py syncdb after the db objects were successfully created, there was the following message:
No fixtures found
I then tried to manually load the fixtures by using the loaddata command:
./manage.py loaddata 0100_foobar.yml
Problem installing fixture '0100_foobar': yml is not a known serialization
Is the documentation given in the link above wrong?, or do I need to install a module in order for django to grok YML?
BTW, the YML files parse correctly and have been checked for correctness (i used them successfully in another project) - so that is not the problem
[Edit]
I have installed PyYaml and renamed my fixtures files as per Manoj's instructions. I am able to get a little further down the line, but I am still encountering problems (BTW, I am using PyYaml 3.0.9).
Here is the Model in my project ORM (i.e. {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)
Here is the YAML file I am importing:
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 Afr开发者_运维技巧ica - 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 }
Here is the stack trace when I run ./manage.py loaddata myapp/fixtures/currencies.yaml
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
I tried to reproduce your problem in one of my projects. Apparently loaddata
expects the extension of the file to match the serialization format. In your case you should rename your file to 0100_foobar.yaml
(note the new extension).
Local tests showed my hypothesis was correct.
PS: YAML serialization requires the PyYAML
library. If you already haven't, install PyYAML.
Update
I copied the OP's model to one of my projects. When I tried to load the sample YAML given by the OP as-is, I got the same error.
After that I added some data using the admin app and used django.core.serializers.serialize
to dump the data in YAML format.
from django.core.serializers import serialize
from app.models import Currency
print serializers.serialize("yaml", Currency.objects.all())
The result I got looked significantly different from what the OP posted. See below. I added three instances for the model and they are showing up.
- 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
I was able to load this data back without any trouble.
Given the above, I suspect that there is something wrong with the OP's YAML file. @skyeagle, can you try dumping the existing data and then try loading the dump back?
For anyone like me who is just stubborn and really, really, wants to use files with a .yml
extension, you can register a serializer at startup to make loaddata
recognize the fixture file:
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')
The call to register_serializer
will register yml
as a recognized extension.
精彩评论