web-dev-qa-db-ja.com

boto3のget_contents_to_fileと同等

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でこれを行うためのより良い方法はありますか?

13
Alasdair

V1.4. 現在 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)

この操作は、 バケットリソース および s3クライアント でも利用できます。例:

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

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

正解は、TemporaryFileの代わりにNamedTemporaryFileを使用することです。

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

1
patito

最も賛成の答えに注意してください。

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.
0
GodBlessYou

Peterの答えは正しいですが、現在AWSの多くにはboto3 1.4がデプロイされておらず、特にAWSLambdaがデプロイされていないことに注意してください。

これにより、オンザフライでのアップグレードが妨げられることはありませんが、新規インストールでコードを実行している場合は、必ず確認してください。

boto3.__version__ >= '1.4.0'

そうでない場合は、ライブラリをアップグレードします。うまくいけば、これはすぐに修正され、これは議論の余地があるでしょう。

0
W. Harris