2011-10-15 40 views
5

我有一些处理Django用户的信号处理程序。另外我使用南方。这些信号处理程序取决于之前必须运行的一些迁移。以编程方式检查syncdb是否正在运行

当Django执行snycdb并创建admin用户时,这些迁移没有运行,信号处理程序引发异常。

我正在寻找一种方法来检测Django当前是否运行syncdb,以便信号handerls可以跳过执行。

+1

南有它的模型和一张表,它记录了哪些信息哪些是迁移已被毁掉,哪些不是。也许你可以用它来检查你需要的迁移是否已经运行? – Ski

+0

这也是一个选项。但由于处理程序是用于保存相对经常保存的模型的保存后信号,因此我希望此时避免额外往返数据库。 –

+1

我认为您可以安全地将这些信息存储在全局变量中,并在应用程序启动时只检索一次。 – Ski

回答

0

我不认为有一种方法可以知道是否执行syncdb正在运行,但有一种方法来处理Python异常:

正好赶上和异常和pass

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

虽然这是一个选项,但我不想在处理程序中吞下一个DatabaseError,因为这也可能表示其他严重问题。 –

0

AFAIK无法检测syncdb是否正在运行,但是,当syncdb或loaddata正在运行时,您的信号将收到原始的额外参数。

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

这样,您可以跳过syncdb执行时要运行的信号。

+1

只有在数据从夹具中加载时,原始参数才为真。然而,django在初始syncdb过程中创建的一些内容(如初始用户和默认网站)并未从fixtures加载,因此raw会像其他保存场景一样为False。 –

2

我陷阱DatabaseError异常,并检查我试图使用的模型的ContentType条目是否存在,如果它没有,我假设syncdb正在发生,否则回滚事务并重新引发原始异常。只有在引发DatabaseError时,此方法才会产生额外的DB访问权限。

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 
相关问题