我有一些處理Django用戶的信號處理程序。另外我使用南方。這些信號處理程序取決於之前必須運行的一些遷移。以編程方式檢查syncdb是否正在運行
當Django執行snycdb並創建admin用戶時,這些遷移沒有運行,信號處理程序引發異常。
我正在尋找一種方法來檢測Django當前是否運行syncdb,以便信號handerls可以跳過執行。
我有一些處理Django用戶的信號處理程序。另外我使用南方。這些信號處理程序取決於之前必須運行的一些遷移。以編程方式檢查syncdb是否正在運行
當Django執行snycdb並創建admin用戶時,這些遷移沒有運行,信號處理程序引發異常。
我正在尋找一種方法來檢測Django當前是否運行syncdb,以便信號handerls可以跳過執行。
我不認爲有一種方法可以知道是否執行syncdb正在運行,但有一種方法來處理Python異常:
正好趕上和異常和pass
:
try:
# code that deals with django user
except ExceptionYouAreGetting:
# seems like syncdb is running, let's pass for now
pass
雖然這是一個選項,但我不想在處理程序中吞下一個DatabaseError,因爲這也可能表示其他嚴重問題。 –
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執行時要運行的信號。
只有在數據從夾具中加載時,原始參數才爲真。然而,django在初始syncdb過程中創建的一些內容(如初始用戶和默認網站)並未從fixtures加載,因此raw會像其他保存場景一樣爲False。 –
我陷阱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
南有它的模型和一張表,它記錄了哪些信息哪些是遷移已被毀掉,哪些不是。也許你可以用它來檢查你需要的遷移是否已經運行? – Ski
這也是一個選項。但由於處理程序是用於保存相對經常保存的模型的保存後信號,因此我希望此時避免額外往返數據庫。 –
我認爲您可以安全地將這些信息存儲在全局變量中,並在應用程序啓動時只檢索一次。 – Ski