简体   繁体   English

如何从 S3 加载泡菜文件以在 AWS Lambda 中使用?

[英]How to load a pickle file from S3 to use in AWS Lambda?

I am currently trying to load a pickled file from S3 into AWS lambda and store it to a list (the pickle is a list).我目前正在尝试将腌制文件从 S3 加载到 AWS lambda 并将其存储到列表中(腌制是列表)。

Here is my code:这是我的代码:

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)

I get the following error even though the file exists:即使文件存在,我也会收到以下错误:

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

Any ideas?有任何想法吗?

Super simple solution超级简单的解决方案

import pickle
import boto3

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

As shown in the documentation for download_fileobj , you need to open the file in binary write mode and save to the file first.download_fileobj的文档所示,您需要先以二进制写入模式打开文件并保存到文件中。 Once the file is downloaded, you can open it for reading and unpickle.下载文件后,您可以打开它进行阅读和解压。

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 takes the name of an object in S3 plus a handle to a local file, and saves the contents of that object to the file. download_fileobj使用 S3 中对象的名称加上本地文件的句柄,并将该对象的内容保存到文件中。 There is also a version of this function called download_file that takes a filename instead of an open file handle and handles opening it for you.这个函数还有一个叫做download_file的版本,它接受一个文件名而不是一个打开的文件句柄,并为你处理打开它。

In this case it would probably be better to use S3Client.get_object though, to avoid having to write and then immediately read a file.在这种情况下,使用S3Client.get_object可能会更好,以避免必须写入然后立即读取文件。 You could also write to an in-memory BytesIO object, which acts like a file but doesn't actually touch a disk.您还可以写入内存中的 BytesIO 对象,它的作用类似于文件,但实际上并不接触磁盘。 That would look something like this:这看起来像这样:

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)

This is the easiest solution.这是最简单的解决方案。 You can load the data without even downloading the file locally using S3FileSystem您甚至可以使用S3FileSystem加载数据而无需在本地下载文件

from s3fs.core import S3FileSystem
s3_file = S3FileSystem()

data = pickle.load(s3_file.open('{}/{}'.format(bucket_name, file_path)))

According to my implementation, S3 file path read with pickle.根据我的实现,S3 文件路径用 pickle 读取。

import pickle
import boto3

name = img_url.split('/')[::-1][0]
folder = 'media'
file_name = f'{folder}/{name}'
bucket_name = bucket_name
s3 = boto3.client('s3', aws_access_key_id=aws_access_key_id,aws_secret_access_key=aws_secret_access_key)
response = s3.get_object(Bucket=bucket_name, Key=file_name)
body = response['Body'].read()
data = pickle.loads(body)  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM