即使密钥存在,S3 也会给我 NoSuchKey 错误

问题描述 投票:0回答:7

这是我的 boto3 命令,用于从 S3 存储桶获取具有特定密钥的对象:

resp = s3client.get_object(Bucket='<>-<>', Key='MzA1MjY1NzkzX2QudHh0')

它给出以下错误:

botocore.errorfactory.NoSuchKey: An error occurred (NoSuchKey) when calling the GetObject operation: The specified key does not exist.

我已检查过桶,密钥确实存在

我错过了什么还是我做错了什么?

amazon-s3 boto3
7个回答
11
投票

您的 URL 末尾有一个 %0A;这是一个行分隔符。


8
投票

由于您知道您拥有的密钥肯定在您要查找的文件的名称中,因此我建议使用

filter
来获取名称以您的密钥作为前缀的对象。

s3 = boto3.resource('s3')
bucket = s3.Bucket('cypher-secondarybucket')
for obj in bucket.objects.filter(Prefix='MzA1MjY1NzkzX2QudHh0'):
    print obj.key

当您运行此代码时,您将获得以您的密钥开头的所有文件的密钥名称。这将帮助您找出您的文件在 S3 上的确切名称。


7
投票

通用答案可能对那些正在考虑文件路径并且可能对 AWS S3 术语不熟悉的人有用。未正确获取“name”和“key”通常会导致异常,并显示此问题中发布的消息

An error occurred (NoSuchKey)...

假设您有一个 JPEG 文件存储在存储桶中的某个“路径”中。在 AWS 控制台上导航到此对象将显示 S3 URI:

s3://my-bucket/some/very/long/path/my-image.jpeg

您可以通过以下基本示例读取 Python 中的

my-image.jpeg
对象:

import boto3

s3client = boto3.client('s3', region_name='us-east-1')

bucket_name = 'my-bucket'
object_key = 'some/very/long/path/my-image.jpeg'

try:
    s3obj = s3client.get_object(Bucket=bucket_name, Key=object_key)
except Exception as e:
    print(f"Error reading key {object_key} from bucket {bucket_name}: {e}")
else:
   print(f"Got object: {s3obj}")

0
投票

我遇到的另一个可能导致对象的 url 中出现行分隔符的问题是,在用于获取对象密钥的 AWS documentation 之一中,将此代码显示为获取对象密钥的示例。

foreach ($results as $result) {
    foreach ($result['Contents'] as $object) {
        echo $object['Key'] . PHP_EOL;
    }
}

问题是最后的

PHP_EOL
。只需将其移除,行分隔符就会消失。

$object['Key'] . PHP_EOL;
-->
$object['Key'];


0
投票
from urllib.parse import unquote
key = "MzA1MjY1NzkzX2QudHh0%0A"

key = unquote(key)

这将从任何键中删除所有特殊字符。


0
投票

在我的例子中,对象

key
来自第 3 方 API 作为
/path/to/object.ext
NoSuchKey
错误是由于
key
参数上的前导斜杠造成的。

其他命令,例如

CopyObjectCommand
有一个
CopySource
参数,因此
bucket-name/path/to/object.ext
适用于此,但对于
GetObject
bucket
key
是单独的参数。

删除前导

/
可以清除这种情况下的错误


0
投票

这个问题让我卡了3个多小时|

  1. 首先我更新了 IAM 以允许 getobject 权限
  2. 其次我在复制命令之前添加了一个服务员

我的代码看起来有点像这样

    copy_source = {'Bucket': source_bucket, 'Key': object_key}
        
        waiter = s3_client.gt_waiter('object_exists')
        waiter.wait(Bucket=source_bucket, Key=object_key)

        s3_client.copy_object(Bucket=target_bucket, Key=object_key, CopySource=
copy_source)
© www.soinside.com 2019 - 2024. All rights reserved.