views:

46

answers:

1

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 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 }

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
+1  A: 

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?

Manoj Govindan
@manoj: Thanks for the answer - it would have taken me a long time to figure out the filename extension change required. I am still having problems after following your advice. I have modified my question to reflect the new state of affairs. Is there something wrong with my YML file ? It works fine in another project ...
skyeagle
@manoj: Thanks for the detective work. I think I will be able to fix my problem from this point onward. I've got to dash off to catch a flight. I'll accept your answer now, and I'll try to work it out later on in the day today.
skyeagle