2010-10-07 7 views
5

He creado con éxito mi primer proyecto django.¿Django grok YML? django no carga los archivos YML (yml no es una serialización conocida)

Tengo dos aplicaciones en mi proyecto foo y foobar.

He creado una carpeta llamada 'accesorios' en cada una de las carpetas de la aplicación. NO he especificado un directorio de accesorios en mi settings.yml, así que (according to the docs), django debería buscar en mi carpeta {app}/fixtures.

En la carpeta {app}/fixtures, tengo varios archivos YML. He dividido los datos iniciales de los distintos módulos en archivos YML separados, asegurándome de que no haya dependencias de archivos cruzados (es decir, todos los modelos relacionados están en el mismo archivo YML y los antepasados ​​aparecen en el archivo antes que 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 se encontraron accesorios

Luego trató de cargar manualmente 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 renombré mis archivos de accesorios según las instrucciones de Manoj. Puedo avanzar un poco más, pero sigo teniendo problemas (por cierto, estoy usando PyYaml 3.0.9).

Aquí es 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á la pila rastrear cuando corro ./manage.py loaddata miaplicacion/accesorios/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

He votado para cerrarlo. Con suerte, otros estarán de acuerdo y lo eliminarán. –

+0

Gracias Manoj. Pensé que tenía la respuesta, pero resulta que estaba equivocado, así que volví a enviar la pregunta, modificada ligeramente para reflejar mis nuevos hallazgos – skyeagle

+0

¡Uy! Desafortunadamente no puedo retirar mi voto. –

Respuesta

7

traté de reproducir el problema en uno de mi proyecto s. Aparentemente loaddata espera la extensión del archivo para que coincida con el formato de serialización. En su caso, debe cambiar el nombre de su archivo al 0100_foobar.yaml (tenga en cuenta la nueva extensión).

Las pruebas locales mostraron que mi hipótesis era correcta.

PS: la serialización YAML requiere la biblioteca PyYAML. Si ya no lo tiene, instale PyYAML.

actualización

he copiado el modelo de la OP a uno de mis proyectos. Cuando traté de cargar la muestra YAML dada por el OP tal como está, obtuve el mismo error .

Después de eso me añaden algunos datos mediante la aplicación de administración y usados ​​django.core.serializers.serialize 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 se vio significativamente diferente de lo publicado por el OP. Vea abajo. Agregué tres instancias para el modelo y están apareciendo.

- 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 

Pude volver a cargar esta información sin ningún problema.

Dado lo anterior, sospecho que hay algo mal con el archivo YAML de la OP. @skyeagle, se puede tratar vertido los datos existentes y luego intente cargar el volcado de vuelta?

+0

Gracias por la respuesta - que me habría llevado mucho tiempo para averiguar el nombre del archivo cambio de extensión requerido. Sigo teniendo problemas después de seguir tu consejo. He modificado mi pregunta para reflejar el nuevo estado de cosas. ¿Hay algún problema con mi archivo YML? Funciona bien en otro proyecto ... – skyeagle

+0

Gracias por el trabajo de detective. Creo que podré solucionar mi problema a partir de ahora. Tengo que salir corriendo para tomar un vuelo. Aceptaré su respuesta ahora, y trataré de resolverlo más adelante en el día de hoy. – skyeagle

+0

Me faltaba PyYAML; gracias. Ver https://docs.djangoproject.com/en/1.6/topics/serialization/#serialization-formats. – Seth

1

Para alguien 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 reconocen 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.

Cuestiones relacionadas