相当于boto3中的get_contents_to_file

Equivalent to get_contents_to_file in boto3

在 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 with 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 中有更好的方法吗?

正确答案是使用 NamedTemporaryFile 而不是 TemporaryFile:

with NamedTemporaryFile() as tmp_file:
    file_name = tmp_file.name # This is what you are looking for

这里有更多文档:https://docs.python.org/2/library/tempfile.html

V1.4.0 there is a 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 and s3 client上也可以操作,例如:

import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')

with open('filename', 'wb') as data:
    bucket.download_fileobj('mykey', data)

Peter 的回答是正确的,但我想指出,目前大部分 AWS 没有部署 boto3 1.4,尤其是 AWS Lambda。

这不会阻止您即时升级,但如果您在全新安装时运行代码,请务必检查

boto3.__version__ >= '1.4.0'

如果没有,请升级库。希望这将很快得到解决,这将是没有实际意义的。

请注意点赞数最高的回答。

get_contents_to_filedownload_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.