Est-ce que django grok YML? django pas des accessoires fixes du chargement du fichier YML (YML est pas une sérialisation connue)
-
28-09-2019 - |
Question
Je l'ai créé avec succès mon premier projet django.
J'ai deux applications dans mon projet foo et foobar.
J'ai créé un dossier nommé « Fixtures » dans chacun des dossiers d'applications. Je n'ai pas spécifié un dans mon settings.yml, donc ( selon la docs ), django doit être regarder dans mon {app} / dossier fixtures.
Dans la {app} / dossier fixtures, j'ai plusieurs fichiers YML. J'ai divisé les données initiales pour les différents modules dans des fichiers YML séparés, en vous assurant qu'il n'y a pas de dépendances de fichiers croisés (tous les modèles connexes sont dans le même fichier YML et ancêtres se produisent dans le fichier avant que 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é
I a ensuite tenté de charger manuellement les appareils à l'aide de 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 installer un module afin de django à grok YML?
BTW, les fichiers YML correctement analyser et ont été vérifiés 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 fixtures selon les instructions de Manoj. Je suis en mesure d'obtenir un peu plus loin sur la ligne, mais je suis toujours des problèmes (rencontrais BTW, j'utilise PyYAML 3.0.9).
Voici le modèle dans mon projet ORM (à savoir {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 trace de la pile quand je lance ./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
La solution
J'ai essayé de reproduire votre problème dans l'un de mes projets. Apparemment loaddata
attend le extension du fichier pour correspondre au format de sérialisation. Dans votre cas, vous devez renommer votre fichier à 0100_foobar.yaml
(notez la nouvelle extension).
tests locaux a montré mon hypothèse était correcte.
PS : sérialisation YAML nécessite la bibliothèque PyYAML
. Si vous avez déjà pas, installez PyYAML .
Mise à jour
Je copié le modèle de l'OP à l'un de mes projets. Lorsque j'ai essayé de charger l'échantillon YAML donnée par l'OP en l'état, je suis même erreur.
Après que j'ai ajouté quelques données à l'aide de l'application admin 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 je me suis regardé significativement différent de ce que l'OP affiché. Voir ci-dessous. J'ai ajouté trois cas pour le modèle et ils font leur apparition.
- 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 pu charger ce dos de données sans aucun problème.
Compte tenu de ce qui précède, je soupçonne qu'il ya quelque chose de mal avec le fichier YAML de l'OP. @skyeagle, pouvez-vous essayer Dumping les données existantes et puis essayez de charger le dos de vidage?
Autres conseils
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
enregistrera yml
comme une extension reconnue.