2011-10-15 14 views
5

Tengo algunos controladores de señal que funcionan en el usuario de Django. Además estoy usando el sur. Estos manejadores de señal dependen de algunas migraciones que deben ejecutarse antes.Verifica programáticamente si se está ejecutando syncdb

Cuando Django ejecutó snycdb y creó el usuario administrador, estas migraciones no se han ejecutado y los manejadores de señal presentan una excepción.

Estoy buscando una forma de detectar si Django actualmente ejecuta syncdb para que los ejecutores de señales puedan omitir la ejecución.

+1

del Sur tiene su modelo y una mesa donde se registra la información, que las migraciones se ha runed y los que no lo era. ¿Tal vez podrías usar eso para verificar si las migraciones que necesitas han sido ejecutadas? – Ski

+0

Esto también sería una opción. Pero dado que los manipuladores son para señales de posguarda en modelos relativamente guardados a menudo, me gustaría evitar un viaje de ida y vuelta adicional al DB en este momento. –

+1

Creo que puede almacenar esa información de forma segura en una variable global y recuperarla solo una vez cuando se inicia la aplicación. – Ski

Respuesta

0

No creo que hay una manera de saber si syncdb está en marcha, pero hay una manera de manejar excepciones en Python:

Sólo de captura y excepción y pass:

try: 
    # code that deals with django user 
except ExceptionYouAreGetting: 
    # seems like syncdb is running, let's pass for now 
    pass 
+1

Si bien esta es una opción, no quiero tragar un 'DatabaseError' en el manejador porque esto también podría indicar otros problemas serios. –

0

yo sepa no es posible detectar si syncdb se está ejecutando o no, sin embargo, cuando se ejecutan syncdb o loaddata, sus señales recibirán un argumento extra sin procesar.

@receiver(post_save, sender=ModelA) 
def signal_handler(sender, **kwargs): 
    raw = kwargs.get('raw', False) 
    if not raw: 
     <do whatever> 

De esta manera, puede omitir las señales que se ejecutarán cuando se está ejecutando syncdb.

+1

El argumento en bruto solo es verdadero si los datos se están cargando desde un dispositivo. Sin embargo, algunas cosas (como el usuario inicial y el sitio predeterminado) que crea django durante el proceso syncdb inicial no se cargan desde dispositivos, por lo que será falso como en cualquier otro escenario de guardado. –

2

Intento la excepción DatabaseError y compruebo si existe la entrada ContentType para el modelo que estoy tratando de usar, si no asumo que syncdb está sucediendo, de lo contrario retrotrae la transacción y vuelva a subir la excepción original. Este método incurre en un acceso de base de datos adicional solo cuando se genera DatabaseError.

with transaction.commit_on_success(): 
     try: 
      content_type = ContentType.objects.get_for_model(kwargs['instance']) 
      for relation in WorkflowTypeRelation.objects.filter(content_type=content_type): 
       workflow_instance = WorkflowInstance.objects.create(content_object=kwargs['instance'], 
        workflow_type=relation.workflow_type) 
     except DatabaseError as database_error: 
      try: 
       ContentType.objects.get(model='workflowtyperelation') 
      except ContentType.DoesNotExist: 
       # Most probable running during syncdb phase, 
       # so ignore the exception 
       pass 
      except DatabaseError: 
       # ContentType model DB table doesn't exists, 
       # raise original exception 
       raise database_error 
      else: 
       # The ContentType model exists, 
       # there is something wrong with the DB 
       # raise original exception 
       transaction.rollback() 
       raise database_error 
Cuestiones relacionadas