在boto3中,是否有等价的get_contents_to_file
,它将对象的内容复制到文件句柄中?
在boto中,如果我有一个S3对象key
,我可以将内容复制到一个临时文件中:
from tempfile import TemporaryFile
key = code_that_gets_key()
with TemporaryFile() as tmp_file:
key.get_contents_to_file(key, tmpfile)
我还没找到boto3中的等价物。
我已将get_contents_to_filename
的使用替换为download_file
。但是,这涵盖了我提供文件名的情况。在这种情况下,我想提供文件句柄作为参数。
目前,我可以通过迭代主体来获取代码在boto3中工作,如下所示:
with TemporaryFile() as tmp_file:
body = key.get()['Body']
for chunk in iter(lambda: body.read(4096), b''):
filehandle.write(chunk)
在boto3中有更好的方法吗?
答案 0 :(得分:10)
从V1.4.0开始,有一个download_fileobj
函数可以完全按照您的要求执行操作。根据正式文件:
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
obj = bucket.Object('mykey')
with open('filename', 'wb') as data:
obj.download_fileobj(data)
此操作也可在bucket resource和s3 client上使用,例如:
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
with open('filename', 'wb') as data:
bucket.download_fileobj('mykey', data)
答案 1 :(得分:1)
正确的答案是使用NamedTemporaryFile而不是TemporaryFile:
with NamedTemporaryFile() as tmp_file:
file_name = tmp_file.name # This is what you are looking for
答案 2 :(得分:0)
彼得的回答是正确的,但我想指出,目前大部分AWS都没有部署boto3 1.4,最值得注意的是AWS Lambda。
这并不能阻止您动态升级,但如果您在新安装时运行代码,请务必检查
boto3.__version__ >= '1.4.0'
如果没有,请升级库。希望这很快就能解决,这将没有实际意义。
答案 3 :(得分:0)
get_contents_to_file 与 download_fileobj 并不完全相同。
get_contents_to_file 可以将s3中的多个文件附加到单个文件对象。 download_fileobj 无法将s3中的多个文件附加到单个文件对象。
仅当您将单个s3文件添加到单个文件对象时,它们的作用相同。
示例:
def download_files(self, s3_key_list, f):
for s3_key, in s3_key_list:
s3_key_object = self.s3_hook.get_key(s3_key, self.s3_bucket)
s3_key_object.get_contents_to_file(f) # append all the s3 files to a single file object
def download_files(self, s3_key_list, f):
for s3_key, in s3_key_list:
s3_key_object = self.s3_hook.get_key(s3_key, self.s3_bucket)
s3_key_object.download_fileobj(f) # unable to do that, it overwrites the object, you have to use a for loop.