我想知道boto3中是否存在一个键。我可以循环桶内容并检查键是否匹配。
但这似乎太长了,也太过分了。Boto3官方文档明确说明了如何做到这一点。
也许我忽略了最明显的一点。有人能告诉我怎么做吗?
我想知道boto3中是否存在一个键。我可以循环桶内容并检查键是否匹配。
但这似乎太长了,也太过分了。Boto3官方文档明确说明了如何做到这一点。
也许我忽略了最明显的一点。有人能告诉我怎么做吗?
当前回答
get()方法非常简单
import botocore
from boto3.session import Session
session = Session(aws_access_key_id='AWS_ACCESS_KEY',
aws_secret_access_key='AWS_SECRET_ACCESS_KEY')
s3 = session.resource('s3')
bucket_s3 = s3.Bucket('bucket_name')
def not_exist(file_key):
try:
file_details = bucket_s3.Object(file_key).get()
# print(file_details) # This line prints the file details
return False
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code'] == "NoSuchKey": # or you can check with e.reponse['HTTPStatusCode'] == '404'
return True
return False # For any other error it's hard to determine whether it exists or not. so based on the requirement feel free to change it to True/ False / raise Exception
print(not_exist('hello_world.txt'))
其他回答
沿着这条线索,有人能得出结论,哪一种方法是检查S3中是否存在对象的最有效方法吗?
我认为head_object可能会赢,因为它只是检查元数据,比实际对象本身更轻
如果你在一个目录或桶中有少于1000个,你可以获得它们的集合,然后检查这个集合中是否有这样的键:
files_in_dir = {d['Key'].split('/')[-1] for d in s3_client.list_objects_v2(
Bucket='mybucket',
Prefix='my/dir').get('Contents') or []}
即使my/dir不存在,这样的代码也可以工作。
http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.list_objects_v2
使用对象。过滤器和检查结果列表是目前为止检查文件是否存在于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)))
我注意到,为了使用botocore.exceptions. clienterror捕获异常,我们需要安装botocore。botocore占用36M的磁盘空间。如果我们使用aws lambda函数,这尤其会产生影响。如果我们只是使用异常,那么我们可以跳过使用额外的库!
我正在验证文件扩展名为'.csv' 如果桶不存在,这将不会抛出异常! 如果桶存在但对象不存在,则不会抛出异常! 如果桶为空,则抛出异常! 如果桶没有权限,就会抛出异常!
代码看起来像这样。请分享你的想法:
import boto3
import traceback
def download4mS3(s3bucket, s3Path, localPath):
s3 = boto3.resource('s3')
print('Looking for the csv data file ending with .csv in bucket: ' + s3bucket + ' path: ' + s3Path)
if s3Path.endswith('.csv') and s3Path != '':
try:
s3.Bucket(s3bucket).download_file(s3Path, localPath)
except Exception as e:
print(e)
print(traceback.format_exc())
if e.response['Error']['Code'] == "404":
print("Downloading the file from: [", s3Path, "] failed")
exit(12)
else:
raise
print("Downloading the file from: [", s3Path, "] succeeded")
else:
print("csv file not found in in : [", s3Path, "]")
exit(12)
Boto 2的Boto。s3.key。Key对象曾经有一个exists方法,通过执行HEAD请求并查看结果来检查Key是否存在于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请求,这是快速的,即使有问题的对象很大,或者bucket中有很多对象。
当然,您可能会检查对象是否存在,因为您计划使用它。如果是这种情况,您可以忘记load(),直接执行get()或download_file(),然后在那里处理错误情况。