Boto 3 で、指定した key が指定した bucket の中にあるかを確かめるには
Boto 3 では、Boto 2 の頃まであった key の存在をたしかめる exists()
にあたるメソッドが無くなっています。ですが、以下のように list_objects()
を使うことで同様の機能を実現できます。
from boto3 import Session
s3client = Session().client('s3')
def exists(bucket: str, key: str) -> bool:
"""
指定した key が指定した bucket の中に存在するか
:param bucket: (str) bucket name
:param key: (str) key
:return: (bool)
"""
contents = s3client.list_objects(Prefix=key, Bucket=bucket).get("Contents")
if contents:
for content in contents:
if content.get("Key") == key:
return True
return False
解説
list_objects()
は以下のような形のハッシュを返します。
{
'IsTruncated': True|False, # 結果が寸断されたか。されていれば True
'Marker': 'string',
'NextMarker': 'string',
'Contents': [
{
'Key': 'string',
'LastModified': datetime(2015, 1, 1),
'ETag': 'string',
'Size': 123,
'StorageClass': 'STANDARD'|'REDUCED_REDUNDANCY'|'GLACIER',
'Owner': {
'DisplayName': 'string',
'ID': 'string'
}
},
],
'Name': 'string',
'Prefix': 'string',
<略>
}
'Contents'
がキモで、ここに該当する key の配列が入ります。該当する key がないと 'Contents'
は返り値に含まれません。したがって、'Contents'
が含まれるかを調べて、そのリスト内の辞書の 'Key'
の値と、引数で与えた key
が一致するものがあれば exists()
にあたる機能を再現できます。
Prefix
に key のフルパス? を指定するのは若干違和感を覚えますが、Prefix とはそういうものだと理解しました。
2017/06/29 追記
以下のケースで正しく動作しないことがあったので、修正しました (thx, @masahiro_toriumi さん)
Prefixはあくまでもキーの接頭辞を指定するものなので、例えば、"MyBucket/aaa.txt"というPrefixでlist_objectをコールした場合、"MyBucket/aaa.txt.bak"などにも引っかかるため、"MyBucket/aaa.txt"というキーが存在するかどうかは正確には判断できない
Author And Source
この問題について(Boto 3 で、指定した key が指定した bucket の中にあるかを確かめるには), 我々は、より多くの情報をここで見つけました https://qiita.com/ikai/items/22281b3cfc9636d8587d著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .