2010-10-07 14 views
5

J'ai réussi à créer mon premier projet django.Est-ce que django grok YML? django ne charge pas les fixtures Fichier YML (yml n'est pas une sérialisation connue)

J'ai deux applications dans mon projet foo et foobar. J'ai créé un dossier nommé 'fixtures' dans chacun des dossiers de l'application. Je n'ai pas spécifié un répertoire fixtures dans mes settings.yml, donc (according to the docs), django devrait regarder dans mon dossier {app}/fixtures.

Dans le dossier {app}/fixtures, j'ai plusieurs fichiers YML. J'ai divisé les données initiales des différents modules en fichiers YML séparés, en vérifiant qu'il n'y a pas de dépendances entre fichiers (tous les modèles liés sont dans le même fichier YML et les ancêtres apparaissent dans le fichier avant les modèles qui les utilisent).

Cependant, quand je run./manage.py syncdb après les objets db ont été créés avec succès, il y avait le message suivant:

Aucun dispositif trouvé

J'ai ensuite essayé de charger manuellement les appareils en utilisant la commande loaddata:

./manage.py loaddata 0100_foobar.yml 
Problem installing fixture '0100_foobar': yml is not a known serialization 

la documentation est donnée dans le lien ci-dessus mal ?, ou dois-je besoin d'installer un module afin de django GROK YML?

BTW, les fichiers YML analyser correctement et ont été vérifiées pour la décision correcte (je les ai utilisés avec succès dans un autre projet) - donc ce n'est pas le problème

[Modifier]

J'ai installé PyYAML et renommé mes fichiers d'appareils selon les instructions de Manoj. Je suis en mesure d'aller un peu plus loin dans la ligne, mais je rencontre toujours des problèmes (BTW, j'utilise PyYaml 3.0.9).

Voici le modèle dans mon projet ORM (ie {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) 

Voici le fichier YAML j'importe:

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 } 

Voici la pile trace quand je lance ./manage.py loaddata myapp/accessoires/currencies.yaml

[email protected]:~/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 
+0

J'ai voté pour le fermer. Espérons que d'autres seront d'accord et l'enlèveront. –

+0

Merci Manoj. Je pensais que j'avais la réponse, mais il se trouve que j'avais tort, donc j'ai soumis à nouveau la question, légèrement modifié pour refléter mes nouvelles découvertes – skyeagle

+0

oups. Malheureusement, je ne peux pas retirer mon vote. –

Répondre

7

J'ai essayé de reproduire votre problème dans l'un de mon projet s. Apparemment, loaddata attend le extension du fichier pour correspondre au format de sérialisation. Dans votre cas, vous devez renommer votre fichier en 0100_foobar.yaml (notez la nouvelle extension).

Des tests locaux ont montré que mon hypothèse était correcte.

PS: La sérialisation YAML nécessite la bibliothèque PyYAML. Si vous ne l'avez pas déjà fait, installez PyYAML.

Mise à jour

Je copié le modèle de l'OP à l'un de mes projets. Quand j'ai essayé de charger l'exemple YAML donné par l'OP tel quel, j'ai eu la même erreur . Après cela, j'ai ajouté quelques données en utilisant l'application d'administration et utilisé django.core.serializers.serialize pour vider les données au format YAML.

from django.core.serializers import serialize 
from app.models import Currency 
print serializers.serialize("yaml", Currency.objects.all()) 

Le résultat obtenu est très différent de ce que l'OP a affiché. Voir ci-dessous. J'ai ajouté trois instances pour le modèle et elles apparaissent.

- 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 

J'ai été capable de recharger ces données sans problème. Étant donné ce qui précède, je soupçonne qu'il y a un problème avec le fichier YAML de l'OP. @skyeagle, pouvez-vous essayer dumping les données existantes et puis essayez de recharger la décharge?

+0

Merci pour la réponse - il m'aurait fallu beaucoup de temps pour comprendre le nom de fichier changement d'extension requis. J'ai toujours des problèmes après avoir suivi vos conseils. J'ai modifié ma question pour refléter la nouvelle situation. Y at-il un problème avec mon fichier YML? Cela fonctionne bien dans un autre projet ... – skyeagle

+0

Merci pour le travail de détective. Je pense que je serai capable de résoudre mon problème à partir de ce moment. Je dois partir pour prendre un vol. Je vais accepter votre réponse maintenant, et j'essaierai de la régler plus tard dans la journée aujourd'hui. – skyeagle

+0

Il me manquait PyYAML; Je vous remercie. Voir https://docs.djangoproject.com/fr/1.6/topics/serialization/#serialization-formats. – Seth

1

Pour quelqu'un comme moi qui est juste têtu et vraiment, vraiment, veut utiliser des fichiers avec une extension .yml, vous pouvez enregistrer un sérialiseur au démarrage pour faire loaddata reconnaître le fichier de fixation:

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') 

L'appel à register_serializer va enregistrer yml comme une extension reconnue.