Python 使用 Boto3 将文件上传到带有前缀的 S3 存储桶

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37017244/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 18:42:28  来源:igfitidea点击:

Uploading a file to a S3 bucket with a prefix using Boto3

pythonamazon-s3boto3

提问by foxes

I am attempting to upload a file into a S3 bucket, but I don't have access to the root level of the bucket and I need to upload it to a certain prefix instead. The following code:

我正在尝试将文件上传到 S3 存储桶,但我无权访问存储桶的根级别,我需要将其上传到某个前缀。以下代码:

import boto3
s3 = boto3.resource('s3')
open('/tmp/hello.txt', 'w+').write('Hello, world!')
s3_client.upload_file('/tmp/hello.txt', bucket_name, prefix+'hello-remote.txt')

Gives me an error:

给我一个错误:

An error occurred (AccessDenied) when calling the PutObject operation: Access Denied: ClientError Traceback (most recent call last): File "/var/task/tracker.py", line 1009, in testHandler s3_client.upload_file('/tmp/hello.txt', bucket_name, prefix+'hello-remote.txt') File "/var/runtime/boto3/s3/inject.py", line 71, in upload_file extra_args=ExtraArgs, callback=Callback) File "/var/runtime/boto3/s3/transfer.py", line 641, in upload_file self._put_object(filename, bucket, key, callback, extra_args) File "/var/runtime/boto3/s3/transfer.py", line 651, in _put_object **extra_args) File "/var/runtime/botocore/client.py", line 228, in _api_call return self._make_api_call(operation_name, kwargs) File "/var/runtime/botocore/client.py", line 492, in _make_api_call raise ClientError(parsed_response, operation_name) ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

An error occurred (AccessDenied) when calling the PutObject operation: Access Denied: ClientError Traceback (most recent call last): File "/var/task/tracker.py", line 1009, in testHandler s3_client.upload_file('/tmp/hello.txt', bucket_name, prefix+'hello-remote.txt') File "/var/runtime/boto3/s3/inject.py", line 71, in upload_file extra_args=ExtraArgs, callback=Callback) File "/var/runtime/boto3/s3/transfer.py", line 641, in upload_file self._put_object(filename, bucket, key, callback, extra_args) File "/var/runtime/boto3/s3/transfer.py", line 651, in _put_object **extra_args) File "/var/runtime/botocore/client.py", line 228, in _api_call return self._make_api_call(operation_name, kwargs) File "/var/runtime/botocore/client.py", line 492, in _make_api_call raise ClientError(parsed_response, operation_name) ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

bucket_nameis in the format abcdwhile prefixis in the format a/b/c/d/. I'm not sure if the error is due to the slashes being wrong or if there's some way you can specify the prefix elsewhere, or if I don't have write permissions (although I supposedly do).

bucket_name在格式中abcdprefix在格式中a/b/c/d/。我不确定该错误是否是由于斜杠错误造成的,或者是否有某种方法可以在其他地方指定前缀,或者我没有写权限(尽管我应该这样做)。

This code executes without any errors:

此代码执行时没有任何错误:

for object in output_bucket.objects.filter(Prefix=prefix):
    print(object.key)

Although there is no output as the bucket is empty.

虽然没有输出,因为桶是空的。

回答by John Adjei

I'm assuming you have all this set up:

我假设你已经设置了所有这些:

  1. AWS Access Key ID and Secret Key set up (typically stored at ~/.aws/credentials
  2. You have access to S3 and you know your bucket names & prefixes (subdirectories)
  1. AWS 访问密钥 ID 和秘密密钥设置(通常存储在 ~/.aws/credentials
  2. 您有权访问 S3 并且知道您的存储桶名称和前缀(子目录)

According to the Boto3 S3 upload_filedocumentation, you should upload your upload like this:

根据Boto3 S3upload_file文档,您应该像这样上传您的上传:

upload_file(Filename, Bucket, Key, ExtraArgs=None, Callback=None, Config=None)

upload_file(Filename, Bucket, Key, ExtraArgs=None, Callback=None, Config=None)

import boto3
s3 = boto3.resource('s3')
s3.meta.client.upload_file('/tmp/hello.txt', 'mybucket', 'hello.txt')

The key to note here is s3.meta.client. Don't forget that--it worked for me!

这里要注意的关键是s3.meta.client。不要忘记——它对我有用!

I hope that helped.

我希望这有帮助。

回答by foxes

Turns out I needed SSE:

原来我需要SSE:

transfer = S3Transfer(s3_client)
transfer.upload_file('/tmp/hello.txt', bucket_name, prefix+'hello-remote.txt', extra_args={'ServerSideEncryption': "AES256"})

回答by Ranajit kumar

import boto3

s3 = boto3.resource('s3')
s3.meta.client.upload_file( 'csv1.csv', "bucketname", "prefixna/csv1.csv")