当我需要在服务器上保存文件并将相应的记录放入数据库时,我有功能。我怎样才能确保两个事件都发生?
目前我有以下逻辑,但是有更好的解决方案吗?
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
答案 0 :(得分: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()
优点是您首先将元数据保存在数据库中(根据我的理解样本,可以抛出)。如果它抛出,交易将无法完成,也不会存储任何内容。
如果操作系统写入抛出,则重新引发异常后将无法完成数据库事务。
文件清理,但看起来我需要做更多的工作才能完全安全地保护。