Azure Blob上传成功后删除数据库记录的实现疑问
问题说明
需求:仅当文件成功上传至Azure Blob存储后,才删除数据库中对应的记录;上传失败则保留记录。
当前尝试的实现逻辑:Script1的archival函数调用Script2的task函数,task遍历所有works,逐个调用upload函数尝试上传,上传成功则触发upload_success返回True;archival函数在task执行完成后,遍历works并检查每个work的上传状态(即Script2的upload_success返回值),若为True则删除对应数据库记录。
疑问:该方案是否可行?如何为每个独立的work传递成功状态,让Script1能准确校验?
原代码示例:
Script 1(原代码)
async def archival(): await script2.task(works) for work in works: # implement if statment here upload Script2.upload_success: await gwm.delete_work(work["id"])
Script 2(原代码)
async def upload(): blob_client.upload_blob(content.encode()) upload_success(True) async def task(): try: for work in works: try: await upload() except Exception: return False except Exception as ex: logging.exception(ex) async def upload_success(): return True
方案可行性分析与优化实现
原方案不可行,核心问题在于upload_success是全局函数,无法区分每个独立work的上传状态;且task函数中只要单个work上传失败就直接返回False,会中断后续所有work的上传,同时无法反馈每个work的具体结果。
要实现需求,需要让Script2返回每个work的独立上传状态,以下是优化后的代码:
优化后的Script 2
import logging from azure.storage.blob import BlobClient async def upload(work): # 假设每个work包含上传所需的content和blob路径等信息 try: # 根据work信息初始化blob_client(示例,需根据实际情况调整) blob_client = BlobClient.from_connection_string("<你的连接字符串>", container_name="<容器名>", blob_name=work["blob_path"]) blob_client.upload_blob(work["content"].encode()) return True except Exception as ex: logging.error(f"上传work {work['id']} 失败: {str(ex)}") return False async def task(works): # 记录每个work的上传结果,返回{work_id: 是否成功}的字典 upload_results = {} for work in works: upload_results[work["id"]] = await upload(work) return upload_results
优化后的Script 1
async def archival(works): # 获取每个work的上传结果 upload_results = await script2.task(works) for work in works: # 根据work id校验上传状态 if upload_results.get(work["id"], False): await gwm.delete_work(work["id"]) logging.info(f"已删除work {work['id']} 的数据库记录") else: logging.info(f"work {work['id']} 上传失败,保留数据库记录")
关键改动说明
- 每个work的独立状态追踪:Script2的
task函数返回一个字典,以work的id为键,上传是否成功的布尔值为值,确保每个work的状态被独立记录。 - 上传函数的独立性:
upload函数接收单个work作为参数,处理该work的上传逻辑,成功返回True,失败捕获异常并返回False,不会中断其他work的上传。 - Script1的状态校验:通过
upload_results字典直接匹配每个work的上传状态,仅对上传成功的work执行数据库删除操作。
内容的提问来源于stack exchange,提问作者user19715207
相关产品推荐
相关产品推荐

