Python 使用 boto3 检查 s3 中的存储桶中是否存在密钥
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33842944/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
check if a key exists in a bucket in s3 using boto3
提问by Prabhakar Shanmugam
I would like to know if a key exists in boto3. I can loop the bucket contents and check the key if it matches.
我想知道 boto3 中是否存在密钥。我可以循环存储桶内容并检查密钥是否匹配。
But that seems longer and an overkill. Boto3 official docs explicitly state how to do this.
但这似乎更长,而且有点矫枉过正。Boto3 官方文档明确说明了如何执行此操作。
May be I am missing the obvious. Can anybody point me how I can achieve this.
可能是我错过了显而易见的事情。任何人都可以指出我如何实现这一目标。
采纳答案by Wander Nauta
Boto 2's boto.s3.key.Key
object used to have an exists
method that checked if the key existed on S3 by doing a HEAD request and looking at the the result, but it seems that that no longer exists. You have to do it yourself:
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()
does a HEAD request for a single key, which is fast, even if the object in question is large or you have many objects in your bucket.
load()
对单个键执行 HEAD 请求,速度很快,即使有问题的对象很大或者您的存储桶中有很多对象。
Of course, you might be checking if the object exists because you're planning on using it. If that is the case, you can just forget about the load()
and do a get()
or download_file()
directly, then handle the error case there.
当然,您可能正在检查对象是否存在,因为您打算使用它。如果是这种情况,您可以忘记load()
并直接执行 aget()
或download_file()
,然后在那里处理错误情况。
回答by EvilPuppetMaster
I'm not a big fan of using exceptions for control flow. This is an alternative approach that works in boto3:
我不太喜欢将异常用于控制流。这是一种适用于 boto3 的替代方法:
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('my-bucket')
key = 'dootdoot.jpg'
objs = list(bucket.objects.filter(Prefix=key))
if any([w.key == path_s3 for w in objs]):
print("Exists!")
else:
print("Doesn't exist")
回答by Alexander Truslow
Check out
查看
bucket.get_key(
key_name,
headers=None,
version_id=None,
response_headers=None,
validate=True
)
Check to see if a particular key exists within the bucket. This method uses a HEAD request to check for the existence of the key. Returns: An instance of a Key object or None
检查存储桶中是否存在特定键。此方法使用 HEAD 请求来检查密钥是否存在。返回: Key 对象的实例或 None
from Boto S3 Docs
You can just call bucket.get_key(keyname) and check if the returned object is None.
您可以调用bucket.get_key(keyname) 并检查返回的对象是否为None。
回答by Lucian Thorr
In Boto3, if you're checking for either a folder (prefix) or a file using list_objects. You can use the existence of 'Contents' in the response dict as a check for whether the object exists. It's another way to avoid the try/except catches as @EvilPuppetMaster suggests
在 Boto3 中,如果您使用 list_objects 检查文件夹(前缀)或文件。您可以使用响应字典中“内容”的存在来检查对象是否存在。正如@EvilPuppetMaster 所建议的那样,这是另一种避免 try/except 捕获的方法
import boto3
client = boto3.client('s3')
results = client.list_objects(Bucket='my-bucket', Prefix='dootdoot.jpg')
return 'Contents' in results
回答by o_c
The easiest way I found (and probably the most efficient) is this:
我发现的最简单的方法(可能也是最有效的)是这样的:
import boto3
from botocore.errorfactory import ClientError
s3 = boto3.client('s3')
try:
s3.head_object(Bucket='bucket_name', Key='file_path')
except ClientError:
# Not found
pass
回答by Vitaly Zdanevich
Not only client
but bucket
too:
不仅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')
回答by Vitaly Zdanevich
If you have less than 1000 in a directory or bucket you can get set of them and after check if such key in this set:
如果您在目录或存储桶中的数量少于 1000,您可以获取它们的集合,然后检查此集合中是否存在此类键:
files_in_dir = {d['Key'].split('/')[-1] for d in s3_client.list_objects_v2(
Bucket='mybucket',
Prefix='my/dir').get('Contents') or []}
Such code works even if my/dir
is not exists.
即使my/dir
不存在这样的代码也能工作。
http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.list_objects_v2
http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.list_objects_v2
回答by Vitaly Zdanevich
S3_REGION="eu-central-1"
bucket="mybucket1"
name="objectname"
import boto3
from botocore.client import Config
client = boto3.client('s3',region_name=S3_REGION,config=Config(signature_version='s3v4'))
list = client.list_objects_v2(Bucket=bucket,Prefix=name)
for obj in list.get('Contents', []):
if obj['Key'] == name: return True
return False
回答by Mahesh Mogal
There is one simple way by which we can check if file exists or not in S3 bucket. We donot need to use exception for this
有一种简单的方法可以检查文件是否存在于 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")
回答by Vivek
import boto3
client = boto3.client('s3')
s3_key = 'Your file without bucket name e.g. abc/bcd.txt'
bucket = 'your bucket name'
content = client.head_object(Bucket=bucket,Key=s3_key)
if content.get('ResponseMetadata',None) is not None:
print "File exists - s3://%s/%s " %(bucket,s3_key)
else:
print "File does not exist - s3://%s/%s " %(bucket,s3_key)