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でこれを行うためのより良い方法はありますか?
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)
正解は、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
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.
Peterの答えは正しいですが、現在AWSの多くにはboto3 1.4がデプロイされておらず、特にAWSLambdaがデプロイされていないことに注意してください。
これにより、オンザフライでのアップグレードが妨げられることはありませんが、新規インストールでコードを実行している場合は、必ず確認してください。
boto3.__version__ >= '1.4.0'
そうでない場合は、ライブラリをアップグレードします。うまくいけば、これはすぐに修正され、これは議論の余地があるでしょう。