我想知道boto3中是否存在一个键。我可以循环桶内容并检查键是否匹配。
但这似乎太长了,也太过分了。Boto3官方文档明确说明了如何做到这一点。
也许我忽略了最明显的一点。有人能告诉我怎么做吗?
我想知道boto3中是否存在一个键。我可以循环桶内容并检查键是否匹配。
但这似乎太长了,也太过分了。Boto3官方文档明确说明了如何做到这一点。
也许我忽略了最明显的一点。有人能告诉我怎么做吗?
当前回答
FWIW,这里是我正在使用的非常简单的函数
import boto3
def get_resource(config: dict={}):
"""Loads the s3 resource.
Expects AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be in the environment
or in a config dictionary.
Looks in the environment first."""
s3 = boto3.resource('s3',
aws_access_key_id=os.environ.get(
"AWS_ACCESS_KEY_ID", config.get("AWS_ACCESS_KEY_ID")),
aws_secret_access_key=os.environ.get("AWS_SECRET_ACCESS_KEY", config.get("AWS_SECRET_ACCESS_KEY")))
return s3
def get_bucket(s3, s3_uri: str):
"""Get the bucket from the resource.
A thin wrapper, use with caution.
Example usage:
>> bucket = get_bucket(get_resource(), s3_uri_prod)"""
return s3.Bucket(s3_uri)
def isfile_s3(bucket, key: str) -> bool:
"""Returns T/F whether the file exists."""
objs = list(bucket.objects.filter(Prefix=key))
return len(objs) == 1 and objs[0].key == key
def isdir_s3(bucket, key: str) -> bool:
"""Returns T/F whether the directory exists."""
objs = list(bucket.objects.filter(Prefix=key))
return len(objs) > 1
其他回答
我注意到,为了使用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)
假设您只是想检查一个键是否存在(而不是悄悄地覆盖它),首先进行这个检查。也会检查错误:
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...
在Boto3中,如果您正在检查文件夹(前缀)或使用list_objects的文件。您可以使用响应字典中的“Contents”是否存在来检查对象是否存在。这是另一种避免try/except捕获的方法,就像@EvilPuppetMaster建议的那样
import boto3
client = boto3.client('s3')
results = client.list_objects(Bucket='my-bucket', Prefix='dootdoot.jpg')
return 'Contents' in results
如果您寻找一个与目录等效的键,那么您可能需要这种方法
session = boto3.session.Session()
resource = session.resource("s3")
bucket = resource.Bucket('mybucket')
key = 'dir-like-or-file-like-key'
objects = [o for o in bucket.objects.filter(Prefix=key).limit(1)]
has_key = len(objects) > 0
这适用于父键或等同于文件的键或不存在的键。我尝试了上面喜欢的方法,但在父键上失败了。
有一种简单的方法可以检查文件是否存在于S3桶中。我们不需要为此使用异常
sesssion = boto3.Session(aws_access_key_id, aws_secret_access_key)
s3 = session.client('s3')
object_name = 'filename'
bucket = 'bucketname'
obj_status = s3.list_objects(Bucket = bucket, Prefix = object_name)
if obj_status.get('Contents'):
print("File exists")
else:
print("File does not exists")