【发布时间】:2021-02-23 13:00:22
【问题描述】:
我看到了一些类似的帖子,但不幸的是没有一个对我有帮助。 我有一个 s3 存储桶(在 scaleway 上),我试图简单地列出该存储桶中包含的所有对象,使用 boto3 s3 客户端如下:
s3 = boto3.client('s3',
region_name=AWS_S3_REGION_NAME,
endpoint_url=AWS_S3_ENDPOINT_URL,
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY
)
all_objects = s3.list_objects_v2(Bucket=AWS_STORAGE_BUCKET_NAME)
这段简单的代码以错误响应:
botocore.errorfactory.NoSuchKey: An error occurred (NoSuchKey) when calling the ListObjects operation: The specified key does not exist.
首先,这个错误对我来说似乎不合适,因为我没有指定任何搜索键。我还尝试将Prefix 参数传递给此方法,以将搜索范围缩小到特定的子目录,同样的错误。
其次,我尝试使用 boto3 Resource 而不是 Client 来实现相同的目的,如下:
session = boto3.Session(
region_name=AWS_S3_REGION_NAME,
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY
)
resource = session.resource(
's3',
endpoint_url=AWS_S3_ENDPOINT_URL,
)
for bucket in resource.buckets.all():
print(bucket.name)
该代码绝对不会产生任何结果。令我震惊的一件奇怪的事情是,我在这里的任何地方都没有通过bucket_name,这在aws documentation看来是正常的
我不可能错误地配置客户端,因为我可以在同一个客户端上完美地使用put_object 方法。一个奇怪的地方是:当我想放置一个文件时,我将整个路径传递给put_object 作为Key (因为我发现它是要走的路),但是插入的对象带有预先添加的存储桶名称.所以假设我调用put_object(Key='/path/to/myfile.ext'),对象最终将是/bucket-name/path/to/myfile.ext。
这种奇怪的行为是我问题的关键吗?我该如何调查正在发生的事情,或者是否有其他方法可以尝试列出存储桶文件?
谢谢
编辑:所以,在记录boto3 客户端发送的请求后,我注意到存储桶名称附加到 url,所以它请求 https://<bucket_name>.s3.<region>.<provider>/<bucket-name>/,而不是请求 https://<bucket_name>.s3.<region>.<provider>/<bucket-name>/,这导致NoSuchKey 错误。
我查看了botocore 库,发现了这个:
url = _urljoin(endpoint_url, r['url_path'], host_prefix)
在 botocore.awsrequest 第 252 行,其中 r['url_path'] 包含 /skichic-bucket?list-type=2。所以从这里开始,我应该能够轻松地修补库核心以使其适合我。
另外,Prefix 参数不起作用,无论我传递给它什么,我总是会收到整个存储桶内容,但我想我也可以轻松地修补它。
现在不满意,因为github上没有相关的问题,我不敢相信库中包含我是第一个遇到的错误。
谁能解释这整个混乱? >.
【问题讨论】:
-
最后一个 sn-p 代码不会尝试列出存储桶对象,它会列出您账户中给定区域的所有 S3 存储桶。
-
@jordanm 是的,你是对的,但它没有返回任何东西
-
AWS_S3_ENDPOINT_URL 包含什么?覆盖默认值并不常见。
-
@jordanm OP 使用的是S3-compatible Object Storage - Scaleway,因此需要指定一个端点。
标签: python-3.x amazon-web-services amazon-s3 boto3