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

jkd*_*dev 75 python amazon-s3 boto amazon-web-services boto3

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

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

jkd*_*dev 159

在boto 3中,'Key.set_contents_from_'方法被替换为

例如:

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')
Run Code Online (Sandbox Code Playgroud)

或者,二进制数据可以来自读取文件,如官方文档中所述,比较boto 2和boto 3:

存储数据

存储文件,流或字符串中的数据非常简单:

# 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'))
Run Code Online (Sandbox Code Playgroud)

  • @deepakmurthy 我不知道你为什么会收到这个错误......你需要[提出一个新的堆栈溢出问题](/sf/) 并提供有关该问题的更多详细信息. (2认同)
  • 当我尝试 `s3.Object().put()` 时,我最终得到一个 `content-length` 为零的对象。对我来说 `put()` 只接受字符串数据,但 `put(str(binarydata))` 似乎有某种编码问题。我最终得到的对象大约是原始数据大小的 3 倍,这对我来说毫无用处。 (2认同)

EM *_*Bee 36

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

s3.Bucket('bucketname').upload_file('/local/file/here.txt','folder/sub/path/to/s3key')
Run Code Online (Sandbox Code Playgroud)

http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Bucket.upload_file

  • 这样很好,但是不允许存储当前内存中的数据。 (4认同)
  • 从内存写入与从本地写入文件上传到 s3 相比,性能如何? (3认同)
  • @Reid:对于内存文件,您可以使用s3.Bucket(...)。upload_fileobj()方法。 (2认同)

Uri*_*ren 24

这是从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))
Run Code Online (Sandbox Code Playgroud)

现在你可以使用json.load_s3json.dump_s3使用相同的API loaddump

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
Run Code Online (Sandbox Code Playgroud)

  • 优秀。为了让它工作,我添加了这个额外的位:`...["Body"].read().decode('utf-8')`。 (3认同)

kev*_*kev 24

一个更简洁简洁的版本,我用来将文件即时上传到给定的 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="")
Run Code Online (Sandbox Code Playgroud)

注意:您应该始终将您的 AWS 凭证(aws_access_key_idaws_secret_access_key)放在一个单独的文件中,例如-~/.aws/credentials

  • @HammanSamuel,您可以将其存储为“C:\Users\username\.aws\credentials” (2认同)

Fra*_*nke 17

在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)
Run Code Online (Sandbox Code Playgroud)

  • @kev,您可以指定文件名“ subfolder / newfile.txt”而不是“ newfile.txt” (2认同)

小智 12

经过一番研究,我发现了这一点。它可以使用简单的 csv writer 来实现。就是将字典直接写入CSV到S3桶中。

例如: data_dict = [{"Key1": "value1", "Key2": "value2"}, {"Key1": "value4", "Key2": "value3"}] 假设所有字典中的键是制服。

import csv
import boto3

# Sample input dictionary
data_dict = [{"Key1": "value1", "Key2": "value2"}, {"Key1": "value4", "Key2": "value3"}]
data_dict_keys = data_dict[0].keys()

# creating a file buffer
file_buff = StringIO()
# writing csv data to file buffer
writer = csv.DictWriter(file_buff, fieldnames=data_dict_keys)
writer.writeheader()
for data in data_dict:
    writer.writerow(data)
# creating s3 client connection
client = boto3.client('s3')
# placing file to S3, file_buff.getvalue() is the CSV body for the file
client.put_object(Body=file_buff.getvalue(), Bucket='my_bucket_name', Key='my/key/including/anotherfilename.txt')
Run Code Online (Sandbox Code Playgroud)


Uri*_*ren 5

值得一提的是作为后端使用的smart-open 。boto3

smart-open是 python 的直接替代品open,可以从、 、s3和许多其他协议打开文件。ftphttp

例如

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

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

  • 虽然此响应提供了丰富的信息,但它并没有回答最初的问题 - 即某些 boto 方法的 boto3 等价物是什么。 (4认同)
  • 智能打开使用boto3 (3认同)