Hace Django grok YML? django no cargar accesorios archivo YML (yml no es una serialización conocida)
-
28-09-2019 - |
Pregunta
He creado con éxito mi primer proyecto Django.
Tengo dos aplicaciones en mi foo del proyecto y foobar.
He creado una carpeta llamada 'accesorios' en cada una de las carpetas de aplicaciones. Yo no se ha especificado un directorio de fixtures en mi settings.yml, por lo que ( de acuerdo con el docs ), Django debe buscar en mi {app} / carpeta de accesorios.
En el {app} / carpeta de accesorios, tengo varios archivos YML. Tengo dividir los datos iniciales de los distintos módulos en archivos YML separados, asegurándose de que no hay interdependencia entre archivos transversales (es decir, todos los modelos relacionados están en el mismo archivo YML y antepasados ??se producen en el archivo antes de los modelos que los utilizan).
Sin embargo, cuando run./manage.py syncdb después de que los objetos de base de datos se han creado correctamente, no fue el mensaje siguiente:
No hay accesorios encontrados
I intentó entonces manualmente cargar los accesorios utilizando el comando loaddata:
./manage.py loaddata 0100_foobar.yml
Problem installing fixture '0100_foobar': yml is not a known serialization
¿Es la documentación que figura en el enlace anterior equivocada ?, o tengo que instalar un módulo con el fin de Django para asimilar YML?
Por cierto, los archivos YML analizar correctamente y se ha verificado su corrección (he usado con éxito en otro proyecto) - por lo que no es el problema
[Editar]
He instalado PyYAML y renombrado mis archivos de accesorios según las instrucciones del Manoj. Soy capaz de conseguir un poco más abajo de la línea, pero todavía estoy encontrando problemas (Por cierto, estoy usando PyYAML 3.0.9).
Aquí está el modelo en mi proyecto ORM (es decir, {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)
Aquí está el archivo YAML Estoy importando:
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 }
Aquí está el seguimiento de la pila cuando corro ./manage.py loaddata miaplicacion / 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
Solución
He intentado reproducir el problema en uno de mis proyectos. Al parecer loaddata
espera que el extensión del archivo para que coincida con el formato de serialización. En su caso, debe cambiar el nombre del archivo a 0100_foobar.yaml
(tenga en cuenta la nueva extensión).
Pruebas locales mostró mi hipótesis era correcta.
PS : YAML serialización requiere la biblioteca PyYAML
. Si ya no tiene, instalar PyYAML .
Actualizar
He copiado el modelo de la OP a uno de mis proyectos. Cuando traté de cargar la muestra YAML propuesta por el OP como está, me dieron el mismo de error.
Después de eso he añadido algunos datos mediante la aplicación de administración y django.core.serializers.serialize
utilizarse para volcar los datos en formato YAML.
from django.core.serializers import serialize
from app.models import Currency
print serializers.serialize("yaml", Currency.objects.all())
El resultado que obtuve veía significativamente diferente de lo que el PO publicado. Vea abajo. Añadí tres instancias para el modelo y que se están presentando.
- 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
yo era capaz de cargar esto de nuevo los datos sin ningún problema.
Teniendo en cuenta lo anterior, sospecho que hay algo mal con el archivo YAML de la OP. @skyeagle, se puede tratar vertido los datos existentes y después intente cargar la parte posterior volcado?
Otros consejos
Para cualquier persona como yo, que es terco y realmente, realmente, quiere usar archivos con la extensión .yml
, se puede registrar un serializador en el arranque para hacer loaddata
reconoce el archivo de datos:
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')
La llamada a register_serializer
registrará yml
como una extensión reconocida.