You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Python SDK遍历Blob跨存储拷贝仅复制最后一个文件问题求助

问题根因

你的代码核心问题是缩进逻辑错误:拷贝Blob的代码块没有放在遍历Blob的内层循环for blob in blobs_list的范围内,仅在每个容器的所有Blob遍历完成后执行一次拷贝,此时blob变量存储的是当前容器最后一个Blob的信息,所以每个容器只会复制最后一个文件,也不会同步新增的其他文件。

同时你的代码还存在几个可优化的问题:

  • 重复实例化源端BlobServiceClient,属于冗余代码
  • 目标端BlobServiceClient在循环中反复创建,无意义且降低执行效率
  • 使用裸except捕获所有异常,容易掩盖权限、网络等其他报错,不便于后续问题排查
修正后的完整代码
from typing import Container
from azure.storage.blob import BlobClient, BlobServiceClient, ContainerClient
from azure.storage.blob import ResourceTypes, AccountSasPermissions
from azure.storage.blob import generate_account_sas    
from datetime import datetime, timedelta
from azure.core.exceptions import ResourceExistsError

today = str(datetime.now().date())
print(today)

# ================================ 源端配置 ===============================
source_connection_string = '' # 源存储账号连接字符串
source_account_key = '' # 源存储账号密钥
# 创建源端客户端 仅需实例化一次
source_blob_service_client = BlobServiceClient.from_connection_string(source_connection_string) 

# ================================ 目标端配置 ===============================
target_connection_string = '' # 目标存储账号连接字符串
# 创建目标端客户端 仅需实例化一次
target_blob_service_client = BlobServiceClient.from_connection_string(target_connection_string)


# 遍历源端所有容器
for container in source_blob_service_client.list_containers(include_metadata=True):
    container_name = container['name']
    print(f"当前处理容器: {container_name}, 元数据: {container['metadata']}")
    print("==========================")
    
    # 生成账号级SAS令牌 每个容器生成一次即可
    sas_token = generate_account_sas(
        account_name = source_blob_service_client.account_name,
        account_key = source_account_key, 
        resource_types = ResourceTypes(object=True, container=True),
        permission= AccountSasPermissions(read=True,list=True),
        expiry = datetime.utcnow() + timedelta(hours=4)
    )
    
    # 获取当前源容器客户端
    source_container_client = source_blob_service_client.get_container_client(container_name)
    # 遍历当前容器下所有Blob
    for blob in source_container_client.list_blobs():
        blob_name = blob.name
        print(f"当前处理Blob: {blob_name}")
        
        # 构造源Blob访问地址
        source_blob_client = BlobClient(
            source_blob_service_client.url,
            container_name = container_name,
            blob_name = blob_name,
            credential = sas_token
        )
        
        # 目标容器命名规则:原容器名+日期 可按需调整
        target_container_name = f"{container_name}{today}"
        # 先创建目标容器 不存在则创建 存在则跳过
        try:
            target_blob_service_client.create_container(target_container_name)
            print(f"已创建目标容器: {target_container_name}")
        except ResourceExistsError:
            # 容器已存在无需处理
            pass
        
        # 执行Blob拷贝
        target_blob_client = target_blob_service_client.get_blob_client(target_container_name, blob_name)
        target_blob_client.start_copy_from_url(source_blob_client.url)
        print(f"已提交拷贝任务: {blob_name} -> {target_container_name}")
验证说明

修正后所有Blob的拷贝逻辑都会在内层循环中逐文件执行,每个容器下的所有文件都会被复制到目标存储对应容器中,新增文件重新运行脚本也会正常同步。

内容的提问来源于stack exchange,提问作者Nayden Van

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 11:54:02