Azure Python SDK:如何处理Blob已存在租赁并打破租赁?
解决Blob租赁已存在的异常处理方案
问题核心
当Blob已存在无限期租赁时,直接调用acquire_lease会抛出异常,且无法直接通过未持有租赁ID的客户端打破租赁。需要先获取现有租赁ID,再强制打破租赁后重新执行下载流程。
优化后的代码实现
1. 导入必要依赖
from azure.core.exceptions import ResourceExistsError from azure.storage.blob import BlobLeaseClient import os from pathlib import Path import time
2. 重构save_blob函数(优化租赁管理)
使用with语句管理租赁,确保下载过程中无论是否出现异常,租赁都会被自动释放,避免遗留无效租赁:
def save_blob(self, local_path, file_name, blob_client): """下载Blob到指定本地路径""" download_file_path = os.path.join(local_path, file_name) Path(download_file_path).touch() # 用with语句自动管理租赁生命周期 with BlobLeaseClient(blob_client, lease_duration=-1) as lease: # 下载时指定租赁,确保操作合法性 with open(download_file_path, "wb") as file: blob_data = blob_client.download_blob(lease=lease) blob_data.download_to_stream(file) # with块结束后自动释放租赁,无需手动调用break_lease
3. 异常处理逻辑(处理租赁已存在情况)
捕获具体的租赁异常,刷新Blob属性获取现有租赁ID,打破租赁后重试下载:
try: print(f"blob name in try: {blob.name}") self.save_blob(local_path, filename, blob_client) blob_count += 1 except ResourceExistsError: # 刷新Blob属性,获取当前租赁ID blob_client.refresh_properties() existing_lease_id = blob_client.lease_id if existing_lease_id: # 创建租赁客户端并打破现有租赁 lease_client = BlobLeaseClient(blob_client, lease_id=existing_lease_id) lease_client.break_lease() # 短暂等待租赁打破生效 time.sleep(2) # 重试下载流程 self.save_blob(local_path, filename, blob_client) blob_count += 1
关键说明
- 捕获具体异常:避免使用裸
except,精准捕获ResourceExistsError(对应租赁已存在的场景),提高代码健壮性。 - 刷新Blob属性:Blob客户端不会自动同步远程属性,必须调用
refresh_properties()才能获取到当前的租赁ID。 - 租赁生命周期管理:使用
with语句管理BlobLeaseClient,确保异常场景下租赁也能被正确释放,避免出现永久锁定的Blob。 - 等待租赁生效:打破租赁后短暂等待(如2秒),确保Azure服务端完成租赁状态同步,避免重试时仍出现租赁冲突。
内容的提问来源于stack exchange,提问作者Rumi
相关产品推荐
相关产品推荐

