2011-10-15 79 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 
相關問題