借助其他账号预签名URL上传文件至AWS S3遇错误求助
问题解决与方案
修复当前代码的错误
你碰到的ValueError: Fileobj must implement read,是因为resp.content是字节类型数据,不符合upload_fileobj要求的带有read()方法的类文件对象。修改后的代码如下:
from requests import get import boto3 s3_client = boto3.client('s3') # 开启流式传输,避免大文件占用过多内存 resp = get("[Presign URL]", stream=True, timeout=9000) # 使用resp.raw(类文件对象)作为上传数据源 s3_client.upload_fileobj(resp.raw, "my-bucket", "xyz/abc/hmm.avro")
直接“移动”文件的可行方案
如果预签名URL对应的源文件本身存储在AWS S3桶中,你可以用S3的服务端复制功能,无需下载再上传,效率更高:
实现方式:使用CopyObject操作
需要先从预签名URL解析出源桶名、源对象路径(或直接向客户端获取这些信息),然后执行复制:
import boto3 s3_client = boto3.client('s3') # 替换为实际的源桶、源对象键,以及目标信息 source_bucket = "source-bucket-name" source_object_key = "path/to/source/file.avro" dest_bucket = "my-bucket" dest_object_key = "xyz/abc/hmm.avro" # 执行S3服务端复制 s3_client.copy_object( Bucket=dest_bucket, Key=dest_object_key, CopySource={'Bucket': source_bucket, 'Key': source_object_key} )
注意:这种方式要求你的AWS账号对源S3对象拥有s3:GetObject权限,对目标桶拥有s3:PutObject权限。如果源文件不在S3中,只能通过下载再上传的方式处理。
内容的提问来源于stack exchange,提问作者Abhishek Patil
相关产品推荐
相关产品推荐

