Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用boto3将文件或数据写入S3对象_Python_Amazon Web Services_Amazon S3_Boto_Boto3 - Fatal编程技术网

Python 如何使用boto3将文件或数据写入S3对象

Python 如何使用boto3将文件或数据写入S3对象,python,amazon-web-services,amazon-s3,boto,boto3,Python,Amazon Web Services,Amazon S3,Boto,Boto3,在boto 2中,您可以使用以下方法写入S3对象: 是否有boto 3等效物?将数据保存到存储在S3上的对象的boto3方法是什么?在boto3中,“Key.set\u contents\u from\u”方法被替换为 例如: import boto3 some_binary_data = b'Here we have some data' more_binary_data = b'Here we have some more data' # Method 1: Ob

在boto 2中,您可以使用以下方法写入S3对象:


是否有boto 3等效物?将数据保存到存储在S3上的对象的boto3方法是什么?

在boto3中,“Key.set\u contents\u from\u”方法被替换为

例如:

import boto3

some_binary_data = b'Here we have some data'
more_binary_data = b'Here we have some more data'

# Method 1: Object.put()
s3 = boto3.resource('s3')
object = s3.Object('my_bucket_name', 'my/key/including/filename.txt')
object.put(Body=some_binary_data)

# Method 2: Client.put_object()
client = boto3.client('s3')
client.put_object(Body=more_binary_data, Bucket='my_bucket_name', Key='my/key/including/anotherfilename.txt')
或者,二进制数据可以来自读取文件,如中所述:

存储数据 存储文件、流或字符串中的数据很容易:

# Boto 2.x
from boto.s3.key import Key
key = Key('hello.txt')
key.set_contents_from_file('/tmp/hello.txt')

# Boto 3
s3.Object('mybucket', 'hello.txt').put(Body=open('/tmp/hello.txt', 'rb'))

boto3还有一种直接上传文件的方法:

s3 = boto3.resource('s3')    
s3.Bucket('bucketname').upload_file('/local/file/here.txt','folder/sub/path/to/s3key')

这里有一个从s3读取JSON的好技巧:

import json, boto3
s3 = boto3.resource("s3").Bucket("bucket")
json.load_s3 = lambda f: json.load(s3.Object(key=f).get()["Body"])
json.dump_s3 = lambda obj, f: s3.Object(key=f).put(Body=json.dumps(obj))
现在,您可以使用与
load
dump
相同的API使用
json.load\u s3
dump

data = {"test":0}
json.dump_s3(data, "key") # saves json to s3://bucket/key
data = json.load_s3("key") # read json from s3://bucket/key

在S3中写入文件之前,不再需要将内容转换为二进制文件。以下示例在S3存储桶中创建一个包含字符串内容的新文本文件(称为newfile.txt):

import boto3

s3 = boto3.resource(
    's3',
    region_name='us-east-1',
    aws_access_key_id=KEY_ID,
    aws_secret_access_key=ACCESS_KEY
)
content="String content to write to a new S3 file"
s3.Object('my-bucket-name', 'newfile.txt').put(Body=content)

一个更简洁的版本,我用它动态地将文件上传到给定的S3存储桶和子文件夹-

import boto3

BUCKET_NAME = 'sample_bucket_name'
PREFIX = 'sub-folder/'

s3 = boto3.resource('s3')

# Creating an empty file called "_DONE" and putting it in the S3 bucket
s3.Object(BUCKET_NAME, PREFIX + '_DONE').put(Body="")
注意:您应该始终将您的AWS凭证(
AWS\u access\u key\u id
AWS\u secret\u access\u key
)放在一个单独的文件中,例如-
~/.AWS/credentials
值得一提的是,它使用
bot3
作为后端

smart-open
是python的
open
的替代品,它可以从
s3
以及
ftp
http
和许多其他协议打开文件

比如说

from smart_open import open
import json
with open("s3://your_bucket/your_key.json", 'r') as f:
    data = json.load(f)

aws凭证通过加载,通常是
~/.aws/
目录中的文件或环境变量。

您可以使用以下代码写入,例如2019年将图像写入S3。为了能够连接到S3,您必须使用命令
pip install awscli
安装AWS CLI,然后使用命令
AWS configure
输入一些凭据:

import urllib3
import uuid
from pathlib import Path
from io import BytesIO
from errors import custom_exceptions as cex

BUCKET_NAME = "xxx.yyy.zzz"
POSTERS_BASE_PATH = "assets/wallcontent"
CLOUDFRONT_BASE_URL = "https://xxx.cloudfront.net/"


class S3(object):
    def __init__(self):
        self.client = boto3.client('s3')
        self.bucket_name = BUCKET_NAME
        self.posters_base_path = POSTERS_BASE_PATH

    def __download_image(self, url):
        manager = urllib3.PoolManager()
        try:
            res = manager.request('GET', url)
        except Exception:
            print("Could not download the image from URL: ", url)
            raise cex.ImageDownloadFailed
        return BytesIO(res.data)  # any file-like object that implements read()

    def upload_image(self, url):
        try:
            image_file = self.__download_image(url)
        except cex.ImageDownloadFailed:
            raise cex.ImageUploadFailed

        extension = Path(url).suffix
        id = uuid.uuid1().hex + extension
        final_path = self.posters_base_path + "/" + id
        try:
            self.client.upload_fileobj(image_file,
                                       self.bucket_name,
                                       final_path
                                       )
        except Exception:
            print("Image Upload Error for URL: ", url)
            raise cex.ImageUploadFailed

        return CLOUDFRONT_BASE_URL + id


botocore.exceptions.NoCredentialsError:找不到凭据如何修复此问题?@deepakmurthy我不知道您为什么会出现此错误。。。您需要查看并提供有关此问题的更多详细信息。当我尝试
s3.Object().put()
时,我得到的对象的内容长度为零。对我来说,
put()
只接受字符串数据,但是
put(str(binarydata))
似乎有一些编码问题。我最终得到了一个大约是原始数据大小3倍的对象,这使得它对我来说毫无用处。@user1129682我不确定这是为什么。你能提供更多细节吗?@jkdev如果你能,那就太好了。太好了。为了让它正常工作,我额外添加了一位:
…[“Body”].read().decode('utf-8')
。好主意。无论如何,它为命名改进提供了一些空间。建议重写这个好主意:这很好,但不允许存储当前内存中的数据。@Reid:对于内存中的文件,可以使用
s3.Bucket(…).upload\u fileobj()
方法。从内存中写入与从本地写入的文件上载到s3的性能如何?不知道我的“put”操作没有访问权限。我创建了这个bucket,并将我的规范id放在访问列表下。在这种情况下,您如何给出
前缀
?这意味着,如果您想将文件存储在
我的bucket name/subfolder/
?@kev,您可以指定与文件名'subfolder/newfile.txt'一起而不是'newfile.txt'是“在S3中写入文件之前,您不再需要将内容转换为二进制文件”,这是否有文档记录?我在看,以为它只接受字节。我不确定到底是什么构成了“可查找的类似文件的对象”,但我不认为它包含字符串。我可能会将其与用于大型多部分文件上载的download_fileobj()进行比较。upload方法需要,但put()允许您将字符串直接写入存储桶中的文件,这便于lambda函数动态创建文件并将文件写入S3存储桶。虽然此响应提供了信息,但它并不坚持回答原始问题,即,某些boto方法的boto3等价物是什么。Smart open使用boto3 AWS凭据文件的Windows等价位置是什么,因为Windows不支持
~
@HammanSamuel您可以像
C:\Users\username\.AWS\credentials