我想知道在boto3中是否存在一个键。我可以循环遍历存储桶内容并检查键是否匹配。
但这似乎过于冗长和繁琐。Boto3官方文档明确说明了如何做到这一点。
也许我忽略了显而易见的方法。有人能告诉我如何实现这个吗。
我想知道在boto3中是否存在一个键。我可以循环遍历存储桶内容并检查键是否匹配。
但这似乎过于冗长和繁琐。Boto3官方文档明确说明了如何做到这一点。
也许我忽略了显而易见的方法。有人能告诉我如何实现这个吗。
Boto 2的boto.s3.key.Key
对象曾经有一个exists
方法,通过执行一个HEAD请求并查看结果来检查S3上是否存在该密钥,但似乎该方法已不再存在。您需要自己进行检查:
import boto3
import botocore
s3 = boto3.resource('s3')
try:
s3.Object('my-bucket', 'dootdoot.jpg').load()
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code'] == "404":
# The object does not exist.
...
else:
# Something else has gone wrong.
raise
else:
# The object does exist.
...
load()
进行一次HEAD请求以获取单个密钥,这非常快速,即使所查询的对象很大或您的存储桶中有许多对象。
当然,您可能正在检查对象是否存在,因为您计划使用它。如果是这种情况,您可以忘记load()
并直接执行get()
或download_file()
,然后在那里处理错误情况。
import boto3
import botocore
from botocore.errorfactory import ClientError
s3 = boto3.client('s3')
try:
s3.head_object(Bucket='bucket_name', Key='file_path')
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code'] == "404":
# The key does not exist.
...
elif e.response['Error']['Code'] == 403:
# Unauthorized, including invalid bucket
...
else:
# Something else has gone wrong.
raise
s3 = boto3.client('s3')
即可。 - Andy Haydenif e.response['ResponseMetadata']['HTTPStatusCode'] == 404:
- Richard我不太喜欢使用异常来控制流程。这是一种在boto3中可行的替代方法:
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('my-bucket')
key = 'dootdoot.jpg'
objs = list(bucket.objects.filter(Prefix=key))
keys = set(o.key for i in objs)
if path_s3 in keys:
print("Exists!")
else:
print("Doesn't exist")
list_objects_v2
函数,将MaxKeys
设为1。 - Fang Zhangbucket.objects.filter(Prefix=key).limit(1)
不会限制S3实际响应的大小,只是在客户端返回的集合上进行了限制。相反,您应该像@FangZhang建议的那样使用bucket.objects.filter(Prefix=key, MaxKeys=1)
。 - Benavimport boto3
client = boto3.client('s3')
results = client.list_objects(Bucket='my-bucket', Prefix='dootdoot.jpg')
return 'Contents' in results
s3:GetObject
权限,只需要s3:ListBucket
权限。 - Vishrant这可以检查前缀和键,最多获取1个键。
def prefix_exits(bucket, prefix):
s3_client = boto3.client('s3')
res = s3_client.list_objects_v2(Bucket=bucket, Prefix=prefix, MaxKeys=1)
return 'Contents' in res
Key1
。要检查确切的键是否存在,最后一行应该修正为类似以下的内容(抱歉代码很丑,我需要在注释中将其放在一行中):return 'Contents' in response and len(response['Contents']) > 0 and 'Key' in response['Contents'][0] and response['Contents'][0]['Key'] == prefix
。 - elshev假设您只想检查键是否存在(而不是静默地覆盖它),请先进行此检查。这也将检查错误:
import boto3
def key_exists(mykey, mybucket):
s3_client = boto3.client('s3')
try:
response = s3_client.list_objects_v2(Bucket=mybucket, Prefix=mykey)
for obj in response['Contents']:
if mykey == obj['Key']:
return 'exists'
return False # no keys match
except KeyError:
return False # no keys found
except Exception as e:
# Handle or log other exceptions such as bucket doesn't exist
return e
key_check = key_exists('someprefix/myfile-abc123', 'my-bucket-name')
if key_check:
if key_check == 'exists':
print("key exists!")
else:
print(f"S3 ERROR: {e}")
else:
print("safe to put new bucket object")
# try:
# resp = s3_client.put_object(Body="Your string or file-like object",
# Bucket=mybucket,Key=mykey)
# ...check resp success and ClientError exception for errors...
import s3fs
s3 = s3fs.S3FileSystem()
s3.exists('myfile.txt')
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('my-bucket')
objs = list(bucket.objects.filter(Prefix=key))
if(len(objs)>0):
print("key exists!!")
else:
print("key doesn't exist!")
这里的“key”是你想要检查是否存在的路径
不仅是client
,还有bucket
:
import boto3
import botocore
bucket = boto3.resource('s3', region_name='eu-west-1').Bucket('my-bucket')
try:
bucket.Object('my-file').get()
except botocore.exceptions.ClientError as ex:
if ex.response['Error']['Code'] == 'NoSuchKey':
print('NoSuchKey')
bucket.Object(key).last_modified
。 - ryanjdillon使用objects.filter
并检查结果列表是目前在S3存储桶中检查文件是否存在的最快方法。
使用这个简洁的一行代码,当你需要将其放入现有项目而不修改太多代码时,它会变得不那么突兀。
s3_file_exists = lambda filename: bool(list(bucket.objects.filter(Prefix=filename)))
bucket
变量。
您可以扩展lambda以支持其他参数,例如:s3_file_exists = lambda filename, bucket: bool(list(bucket.objects.filter(Prefix=filename)))
boto3
,目前最好的方法似乎是调用head_object
尝试获取密钥的元数据,然后处理结果错误如果它不存在。 - Wander Nautaexists
布尔值消失了,并且更清晰(希望如此!)地表明人们应该根据自己的情况进行调整。 - Wander Nautae.response['Error']['Code']
having a value like"NoSuchKey"
, not"404"
. I haven't checked whether this is due to a difference in library versions or a change in the API itself since this answer was written. Either way, in my version of boto3, a shorter approach than checkinge.response['Error']['Code']
is to catch onlys3.meta.client.exceptions.NoSuchKey
in the first place.在我的boto3版本1.5.26上,我看到e.response ['Error'] ['Code']
的值类似于“NoSuchKey”,而不是“404”。 我没有检查这是由于库版本的差异还是API本身的更改。 无论哪种方式,在我的boto3版本中,一个比检查e.response['Error']['Code']
更短的方法是首先仅捕获s3.meta.client.exceptions.NoSuchKey
。 - Mark Amerys3.head_object(Bucket='my_bucket', Key='my_key')
而不是s3.Object(...).load()
。 - sam-6174