这是我的 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.
我已检查过桶,密钥确实存在
我错过了什么还是我做错了什么?
您的 URL 末尾有一个 %0A;这是一个行分隔符。
由于您知道您拥有的密钥肯定在您要查找的文件的名称中,因此我建议使用
filter
来获取名称以您的密钥作为前缀的对象。
s3 = boto3.resource('s3')
bucket = s3.Bucket('cypher-secondarybucket')
for obj in bucket.objects.filter(Prefix='MzA1MjY1NzkzX2QudHh0'):
print obj.key
当您运行此代码时,您将获得以您的密钥开头的所有文件的密钥名称。这将帮助您找出您的文件在 S3 上的确切名称。
通用答案可能对那些正在考虑文件路径并且可能对 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}")
我遇到的另一个可能导致对象的 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'];
from urllib.parse import unquote
key = "MzA1MjY1NzkzX2QudHh0%0A"
key = unquote(key)
这将从任何键中删除所有特殊字符。
在我的例子中,对象
key
来自第 3 方 API 作为 /path/to/object.ext
。 NoSuchKey
错误是由于 key
参数上的前导斜杠造成的。
其他命令,例如
CopyObjectCommand
有一个 CopySource
参数,因此 bucket-name/path/to/object.ext
适用于此,但对于 GetObject
,bucket
和 key
是单独的参数。
删除前导
/
可以清除这种情况下的错误
这个问题让我卡了3个多小时|
我的代码看起来有点像这样
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)