如何使用boto3 Python API将AWS S3存储桶大文件复制到其他S3存储桶
错误触发原因
该错误由S3分块复制的分片范围非法导致,client.copy()方法自动触发分块复制逻辑时,生成了超出源对象实际大小的字节范围请求,常见触发场景如下:
- 所用的boto3/botocore版本存在分块计算bug,当源文件大小为分片大小整数倍时,会错误生成超过源文件大小的最后一个分片区间
- 手动设置的分片大小不符合S3要求:除最后一个分片外,其余分片最小为5MB,最大为5GB
- 复制操作执行过程中源对象被修改,大小发生变动
修复方案
- 优先使用
TransferConfig配置明确的分块参数后再调用copy方法,适配大文件分块复制场景,示例代码如下:
import boto3 from boto3.s3.transfer import TransferConfig s3_client = boto3.client('s3') # 配置分块规则:超过100MB的文件自动触发分块复制,每个分片大小为100MB transfer_config = TransferConfig( multipart_threshold = 100 * 1024 * 1024, multipart_chunksize = 100 * 1024 * 1024, use_threads = True ) copy_source = { 'Bucket': '源存储桶名称', 'Key': '源文件的对象Key' } s3_client.copy( CopySource = copy_source, Bucket = '目标存储桶名称', Key = '目标文件的对象Key', Config = transfer_config )
- 若复制的文件大小小于5GB,可直接使用
copy_object方法避免触发分块复制逻辑:
import boto3 s3_client = boto3.client('s3') s3_client.copy_object( Bucket = '目标存储桶名称', Key = '目标文件的对象Key', CopySource = { 'Bucket': '源存储桶名称', 'Key': '源文件的对象Key' } )
- 升级boto3和botocore到最新版本,修复版本内置的分块计算bug:
升级命令:pip install --upgrade boto3 botocore - 复制前先调用
head_object接口确认源对象大小,避免源对象变动导致的范围错误:
source_obj_meta = s3_client.head_object( Bucket = '源存储桶名称', Key = '源文件的对象Key' ) source_file_size = source_obj_meta['ContentLength']
内容的提问来源于stack exchange,提问作者Sree T
相关产品推荐
相关产品推荐

