2015-12-14 36 views
1

當我需要將文件保存在服務器上並將相應的記錄放入數據庫時​​,我具有功能。我怎樣才能確保兩個事件都不發生?如何回滾數據庫查詢是否尚未保存在服務器上?

現在我有以下邏輯,但有沒有更好的解決方案?

def handle_uploaded_file(filename, file_content, request): 
    # Saves file on the server 
    try: 
     path_to_file = '{}/{}'.format(settings.REPORTS_FOLDER, filename) 
     with open(path_to_file, 'wb+') as destination: 
      for chunk in file_content.chunks(): 
       destination.write(chunk) 
    except IOError: 
     raise 
    # Saves info about uploaded file in the database 
    try: 
     with transaction.atomic(): 
      new_report = Reports(
       path_to_file=path_to_file, 
       document_name=filename, 
       author=request.user, 
       document_type=request.POST['report_type'] 
       ) 
      new_report.save() 
    except IntegrityError: 
     os.remove(path_to_file) 
     raise 
+1

使用交易 – utkbansal

回答

0

考慮下面的代碼:

from django.db import transaction 

@transaction.atomic 
def handle_uploaded_file(filename, file_content, request): 
    path_to_file = '{}/{}'.format(settings.REPORTS_FOLDER, filename) 

    save_file_metadata(filename, path_to_file, request) 
    write_file_contents(file_content, path_to_file) 


def write_file_contents(file_content, path_to_file): 
    try: 
     with open(path_to_file, 'wb+') as destination: 
      for chunk in file_content.chunks(): 
       destination.write(chunk) 
    except IOError: 
     os.remove(path_to_file) 
     raise 


def save_file_metadata(filename, path_to_file, request): 
    new_report = Reports(
      path_to_file=path_to_file, 
      document_name=filename, 
      author=request.user, 
      document_type=request.POST['report_type'] 
    ) 
    new_report.save() 

的好處是,你先保存在數據庫中的元數據(可據我瞭解您的樣品扔)。如果確實拋出,交易將無法完成並且不會存儲內容。

如果操作系統寫入拋出,數據庫事務將不會完成,因爲異常被重新提出。

然而,文件清理看起來需要更多的工作才能完全失效。

相關問題