Pregunta

Tengo un código que lanza causas syncdb para lanzar un error (porque se trata de acceder al modelo antes se crean las tablas).

¿Hay una manera de mantener el código se ejecute en syncdb? algo como:

if not syncdb:
    run_some_code()

Gracias:)

editar :? PS - Pensé en usar la señal post_init ... para el código que tiene acceso a la base de datos, que es una buena idea

Más información

Aquí hay más información que solicitó:)

Me he encontrado este un par de veces, por ejemplo ... yo estaba hackeando en django-cron y determiné que es necesario asegurarse de que los puestos de trabajo que no están vigentes cuando se carga Django (porque se busca en todas las aplicaciones instaladas para puestos de trabajo y los añade a la carga de todos modos).

Por lo tanto, añade el siguiente código al principio del archivo __init__.py:

import sqlite3

try:
        # Delete all the old jobs from the database so they don't interfere with this instance of django
        oldJobs = models.Job.objects.all()
        for oldJob in oldJobs:
                oldJob.delete()
except sqlite3.OperationalError:
        # When you do syncdb for the first time, the table isn't 
        # there yet and throws a nasty error... until now
        pass

Por razones obvias, esto es una porquería. está ligado a SQLite y estoy hay mejores lugares para poner este código (esto es sólo cómo me encontré con el problema), pero funciona.

Como se puede ver el error que se obtiene es un error práctico (en SQLite) y el seguimiento de la pila dice algo en la línea de "django_cron_job mesa no encontrado"

Solución

Al final, el objetivo era ejecutar algún código antes de que se cargan las páginas .

Esto se puede lograr mediante la ejecución en el archivo urls.py, ya que tiene que ser importados antes de una página puede ser servido (obviamente).

Y yo era capaz de eliminar esa fea bloque try / except :) Gracias a Dios (y S. Lott)

¿Fue útil?

Solución

"editar: PS - Pensé en usar la señal post_init ... para el código que tiene acceso a la base de datos, que es una buena idea"

Nunca.

Si tiene código que está accediendo a la modelo antes se crean las tablas, se tienen grandes, grandes problemas. Probablemente se esté haciendo algo muy mal.

Normalmente, se ejecuta syncdb aproximadamente una vez. se crea la base de datos. Y su aplicación web utiliza la base de datos.

A veces, se hizo un cambio de diseño, eliminar y reconstruir la base de datos. Y luego su aplicación web utiliza esa base de datos durante mucho tiempo.

(en general) no es necesario código en un módulo __init__.py. Usted debe (casi) nunca tienen código ejecutable que hace el trabajo real en un módulo __init__.py. Es muy, muy raro, e inadecuado para Django.

No estoy seguro de por qué te estás metiendo __init__.py cuando Django Cron dice que haga sus arreglos de programación en urls.py.


Editar

Eliminación de registros es una cosa.

jugar un poco con __init__.py y base.py de Django-cron están claramente maneras completamente incorrecta de hacer esto. Si es tan complicado, lo estás haciendo mal.

Es imposible saber lo que estás tratando de hacer, pero debería ser trivial.

Su urls.py sólo se puede ejecutar después de syncdb y después de todo el material ORM se ha configurado correctamente y encuadernado.

Su urls.py podría, por ejemplo, eliminar algunas filas y luego añadir algunas filas a una tabla. En este punto, todos los temas son syncdb fuera del camino.

¿Por qué no tiene su lógica en urls.py?

Otros consejos

El código que intenta acceder a los modelos antes de que sean creados pueden existir más o menos sólo en el nivel de módulo; tendría que estar dirigido por el código ejecutable cuando se importa el módulo, como su ejemplo indica. Esto es, como lo has adivinado, la razón por syncdb falla. Se trata de importar el módulo, pero el acto de importar el módulo hace que el código de nivel de aplicación para ejecutar; un "efecto secundario" si se quiere.

El deseo de evitar las importaciones de módulos que causan efectos secundarios es tan fuerte en Python que if __name__ == '__main__': la convención de scripts python ejecutables ha convertido en algo común. Cuando acaba de cargar una biblioteca de código hace que una aplicación para comenzar a ejecutar, dolores de cabeza sobrevienen: -)

Para aplicaciones Django, esto se convierte en más de un dolor de cabeza. Considere el efecto de tener oldJob.delete() ejecutada cada vez que el módulo ha sido importada. Puede parecer que es la ejecución de una sola vez cuando se ejecuta en el servidor de desarrollo de Django, pero en un entorno de producción que conseguirá ejecutado con bastante frecuencia. Si utiliza Apache, por ejemplo, Apache con frecuencia el fuego de varios procesos hijos esperando para atender las peticiones. Como un servidor de larga duración progresa, su aplicación Django conseguirá bootstrap cada vez que un controlador se bifurca para su servidor web, lo que significa que el módulo se importará y delete() será llamado varias veces, a menudo impredecible. Una señal no va a ayudar, por desgracia, ya que la señal podría ser despedido cada vez que un proceso de Apache se inicia también.

No es, por cierto, sólo un servidor web que podría causar su código para ejecutar de forma inadvertida. Si utiliza herramientas como epydoc, por ejemplo, van a importar su código para generar documentación de la API. Esto a su vez podría causar que su lógica de la aplicación para iniciar la ejecución, lo que obviamente es un efecto secundario no deseado de sólo corriendo un programa de análisis de documentación.

Por esta razón, el código de limpieza como esto está bien mejor manejado por una tarea programada, que busca los trabajos de rancias de forma periódica y se limpia la base de datos. Este script personalizado también se puede ejecutar de forma manual, o por cualquier procedimiento (por ejemplo, durante un despliegue, o como parte de su función setUp() prueba de la unidad para asegurar una ejecución de prueba limpia). No importa cómo lo hagas, lo importante es que el código como éste siempre debe ser ejecutado explícitamente , en lugar de implícitamente como resultado de la apertura del archivo de origen.

Espero que ayude. Sé que no proporciona una manera de determinar si syncdb está en marcha, pero el tema syncdb mágicamente desaparecerá si el diseño de su aplicación Django con la implementación de producción en cuenta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top