2013-11-28 28 views
1

我正在使用Django與多個數據庫。我有一個'預覽'數據庫,用於接收用戶上傳的消息,這些數據必須由管理員預覽並'接受',此時他們將被委託給'默認'生產數據庫。下面的觀點應該這樣做,但我得到一個錯誤。每個newSentenceModel對每個newMessageSegment都有一個外鍵,每個newMessageSegment對每個消息都有一個外鍵。如果管理員接受內容,我想將每個項目移動到新的數據庫,然後刪除預覽數據庫中的舊條目。請幫忙!謝謝 -Python的Django多個數據庫提交與外鍵關係的對象

以下是錯誤:

instance is on database "preview", value is on database "default" 

在此行中出現的錯誤消息:

newMessageSegment.msg = newMessage # Setup the foreign key to the msg itself 

這裏是查看功能:

## This view is used when the admin approves content and clicks on the "accept content" button when reviewing 
## a recent upload - it saves the data to the production database 
def accept_content(request, msg_id=None): 
    if msg_id == None: # If for some reason we got a None, then it's not a valid page to accept so redirect home 
     return HttpResponseRedirect("/") # Redirect home 
    msgList = Message.objects.using('preview').all() # Get all Messages 
    msgSegmentList = MessageSegment.objects.using('preview').all() # Get all MessageSegment Objects 
    sentenceModels = SentenceModel.objects.using('preview').all() # Get all SentenceModels 
    for msgs in msgList: # Iterate all msgs 
     if int(msgs.id) != int(msg_id): # Don't care if it is not the msg needing review 
      continue # Short Circuit 
     msgPrimaryKey = msgs.pk # Extract the primary key from this msg to restore later 
     msgs.pk = None # Erase the primary key so we can migrate databases properly 
     newMessage = msgs # This is the msg to transfer to the new one 
     newMessage.save(using='default') # Save the item to the production database 
     for msgSegment in msgSegmentList: # Iterate all msg segments for this msg 
      if msgSegment.msg_id == msgPrimaryKey: # Check the foreign keys on the msg segment to msg connection 
       newMessageSegment = msgSegment # Define a new msg segment 
       msgSegment.pk = None # Erase the primary key so we can assign it properly 
       newMessageSegment.pk = None # Erase the primary key so we can assign it properly 
       newMessageSegment.msg = newMessage # Setup the foreign key to the msg itself 
       newMessageSegment.save(using='default') # Save the item to the production database 
       for sentenceModel in sentenceModels: # Iterate all sentences for this msg segment 
        if sentenceModel.msg_segment_id == msgSegment.id: # Determine which sentences are for this msg segment 
         newSentenceModel = sentenceModel # Define the newSentenceModel 
         newSentenceModel.msg_segment = newMessageSegment # Setup the foreign key to the msg segment 
         newSentenceModel.save(using='default') # Save the item to the production database 
         sentenceModel.delete(using='preview') # Delete the item from the review database 
       msgSegment.delete(using='preview') # Delete the item from the review database 
     msgs.pk = msgPrimaryKey # Restore the key so we can delete it properly 
     msgs.delete(using='preview') # Delete the item from the review database 
    return HttpResponseRedirect("/") 

回答

2

的Django記住哪些數據庫對象被保存着,所以每個newMessageSegment仍然隸屬於preview數據庫,直到您將其保存到default,並且它正確地禁止跨數據庫FK分配。這是未經測試,但它可能工作分配到底層msg_id場來代替:

newMessageSegment.msg_id = newMessage.id 

如果做不到這一點,你可以創建的newMessageSegment新副本,而不僅僅是創建一個新的參考吧。我想你可以通過遍歷msgSegment._meta.fields來實現自動化,但是我可能忽略了繼承的微妙之處。而任何多對多的領域將是一個痛苦。或者,如果你只是想破解它,編輯跟蹤它的內部對象。我通常不會推薦,但是無論如何你都會保存它。

newMessageSegment._state.db = "default" 
newMessageSegment.msg = newMessage 
newMessageSegment.save(using="default") 
+0

非常感謝你 - 改變國家的工作很好。 – PhilBot

+0

第一種方法也可以,謝謝! –