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

fox*_*xes 6 python amazon-s3 boto3

我正在尝试将文件上传到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')
Run Code Online (Sandbox Code Playgroud)

给我一个错误:

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_name是格式abcdprefix的格式a/b/c/d/.我不确定错误是否是由于斜线错误或者是否有某种方式可以在其他地方指定前缀,或者如果我没有写入权限(尽管我应该这样做).

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

for object in output_bucket.objects.filter(Prefix=prefix):
    print(object.key)
Run Code Online (Sandbox Code Playgroud)

虽然铲斗是空的,但没有输出.

小智 14

import boto3

s3 = boto3.resource('s3')
s3.meta.client.upload_file( 'csv1.csv', "bucketname", "prefixna/csv1.csv")
Run Code Online (Sandbox Code Playgroud)


fox*_*xes 8

结果我需要SSE:

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

  • 什么是`s3_client`?它没有在任何地方定义.两者都不是前缀. (6认同)

LoM*_*aPh 8

resource

s3 = boto3.resource('s3')
s3.Bucket('mybucket').upload_file('/tmp/hello.txt', '/detination/s3/path/hello.txt')
Run Code Online (Sandbox Code Playgroud)

client

s3_client = boto3.client('s3')
s3_client.upload_file('/tmp/hello.txt', 'BUCKET_NAME', '/detination/s3/path/hello.txt',)
Run Code Online (Sandbox Code Playgroud)


Joh*_*jei 7

我假设您已完成所有这些设置:

  1. 设置了AWS Access Key ID和Secret Key(通常存储在 ~/.aws/credentials
  2. 您可以访问S3,并且知道您的存储桶名称和前缀(子目录)

根据Boto3 S3 upload_file文档,您应该像这样上载您的上载:

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

这里要注意的关键是s3.meta.client。别忘了-它对我有用!

希望对您有所帮助。

  • 我运行了 `s3_resource.meta.client.upload_file(PATH_IN_COMPUTER, BUCKET_NAME, KEY)` 代码运行没有错误,但文件没有上传。对出了什么问题有什么想法吗? (2认同)

小智 7

这是我的回答:

import boto3

s3_client = boto3.client(service_name='s3', region_name='ap-southeast-1',
                         aws_access_key_id='AWS_ACCESS_KEY_ID',
                         aws_secret_access_key='AWS_SECRET_ACCESS_KEY')

dest_bucket = 'data-lake'
dest_prefix = 'datamart/my_file_name/'

file_name = 'my_file_name'+ '.parquet'

s3.meta.client.delete_object(Bucket=dest_bucket,Key=dest_prefix + file_name)
Run Code Online (Sandbox Code Playgroud)

  • 欢迎来到 StackOverflow。虽然此代码可以回答问题,但提供有关“如何”和/或“为什么”解决问题的附加上下文将提高​​答案的长期价值。 (2认同)

Gwe*_* Au 6

以下是 John Adjei 答案的替代方案。这也取自Boto3 S3 upload_file 文档。因为客户端是低级的(低抽象/更接近机器代码),它可以提高性能 - 特别是如果您处理大数据。

import boto3
s3 = boto3.client('s3')
with open("FILE_NAME", "rb") as f:
    s3.upload_fileobj(f, "BUCKET_NAME", "OBJECT_NAME")
Run Code Online (Sandbox Code Playgroud)

  • 我更喜欢使用 `upload_fileobj()` 的方法,因为我已经在使用文件流,而不是通过文件系统访问文件路径 (2认同)