web-dev-qa-db-ja.com

AWS Lambdaで使用するためにS3からpickleファイルをロードする方法は?

現在、ピクルスされたファイルをS3からAWSラムダにロードして、リストに保存しようとしています(ピクルスはリストです)。

ここに私のコードがあります:

import pickle
import boto3

s3 = boto3.resource('s3')
with open('oldscreenurls.pkl', 'rb') as data:
    old_list = s3.Bucket("pythonpickles").download_fileobj("oldscreenurls.pkl", data)

ファイルが存在しても次のエラーが表示されます。

FileNotFoundError: [Errno 2] No such file or directory: 'oldscreenurls.pkl'

何か案は?

10
mifin

download_fileobj のドキュメントに示されているように、バイナリwriteモードでファイルを開いて保存する必要があります最初にファイル。ファイルがダウンロードされたら、読み取り用に開いて、ピクルスを外すことができます。

import pickle
import boto3

s3 = boto3.resource('s3')
with open('oldscreenurls.pkl', 'wb') as data:
    s3.Bucket("pythonpickles").download_fileobj("oldscreenurls.pkl", data)

with open('oldscreenurls.pkl', 'rb') as data:
    old_list = pickle.load(data)

download_fileobjは、S3のオブジェクトの名前とローカルファイルへのハンドルを取り、そのオブジェクトの内容をファイルに保存します。 download_file と呼ばれるこの関数のバージョンもあります。これは、開いているファイルハンドルの代わりにファイル名を取り、それを開いて処理します。

この場合、おそらく S3Client.get_object を使用する方が、ファイルを書き込んですぐに読み取らなくて済むようになります。また、メモリのBytesIOオブジェクトに書き込むこともできます。このオブジェクトは、ファイルのように機能しますが、実際にはディスクには触れません。これは次のようになります。

import pickle
import boto3
from io import BytesIO

s3 = boto3.resource('s3')
with BytesIO() as data:
    s3.Bucket("pythonpickles").download_fileobj("oldscreenurls.pkl", data)
    data.seek(0)    # move back to the beginning after writing
    old_list = pickle.load(data)
8
avigil

超シンプルなソリューション

import pickle
import boto3

s3 = boto3.resource('s3')
my_pickle = pickle.loads(s3.Bucket("bucket_name").Object("key_to_pickle.pickle").get()['Body'].read())
8
kindjacket