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()
a get()
또는 download_file()
직접 수행 한 다음 오류 사례를 처리하십시오.
boto3
현재 할 수있는 최선의 방법은 전화 head_object
하여 키의 메타 데이터를 가져 와서 결과 오류가없는 경우 처리하는 것입니다.
exists
부울이 사라지 도록 예제 코드를 약간 수정했으며 사람들 이이 상황에 맞게해야한다는 것이 더 분명합니다.
e.response['Error']['Code']
같은 값이 "NoSuchKey"
아닌 것을 알 수 "404"
있습니다. 이 답변이 작성된 이후 라이브러리 버전의 차이 또는 API 자체의 변경으로 인한 것인지 여부는 확인하지 않았습니다. 어느 쪽이든, 내 버전의 boto3에서 확인하는 것보다 짧은 접근법 은 처음 e.response['Error']['Code']
부터 잡는 것 s3.meta.client.exceptions.NoSuchKey
입니다.
client
(a와 달리 resource
)s3.head_object(Bucket='my_bucket', Key='my_key')
s3.Object(...).load()
나는 제어 흐름에 예외를 사용하는 것을 좋아하지 않습니다. 이것은 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")
내가 찾은 가장 쉬운 방법은 아마도 가장 효율적인 방법입니다.
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
s3 = boto3.client('s3')
if e.response['ResponseMetadata']['HTTPStatusCode'] == 404:
Boto3에서 폴더 (접두사) 또는 list_objects를 사용하는 파일을 확인하는 경우 응답 dict에 'Contents'의 존재를 객체의 존재 여부를 확인하는 데 사용할 수 있습니다. @EvilPuppetMaster가 제안한 것처럼 시도 / 제외 캐치를 피하는 또 다른 방법입니다
import boto3
client = boto3.client('s3')
results = client.list_objects(Bucket='my-bucket', Prefix='dootdoot.jpg')
return 'Contents' in results
s3:GetObject
권한 만 s3:ListBucket
권한을
뿐만 아니라 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
.
S3F 를 사용할 수 있습니다 . 이는 전형적인 파일 시스템 스타일 작업을 노출시키는 boto3 주위의 래퍼입니다.
import s3fs
s3 = s3fs.S3FileSystem()
s3.exists('myfile.txt')
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)
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
조용히 덮어 쓰지 않고 키가 있는지 확인하려는 경우 먼저 다음을 확인하십시오.
import boto3
def key_exists(mykey, mybucket):
s3_client = boto3.client('s3')
response = s3_client.list_objects_v2(Bucket=mybucket, Prefix=mykey)
if response:
for obj in response['Contents']:
if mykey == obj['Key']:
return True
return False
if key_exists('someprefix/myfile-abc123', 'my-bucket-name'):
print("key exists")
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...
디렉토리 또는 버킷에 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_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
boto3의 경우, ObjectSummary 를 사용하여 오브젝트가 존재하는지 확인할 수 있습니다.
Amazon S3 버킷에 저장된 객체의 요약을 포함합니다. 이 개체는 개체의 전체 메타 데이터 또는 내용을 포함하지 않습니다.
import boto3
from botocore.errorfactory import ClientError
def path_exists(path, bucket_name):
"""Check to see if an object exists on S3"""
s3 = boto3.resource('s3')
try:
s3.ObjectSummary(bucket_name=bucket_name, key=path).load()
except ClientError as e:
if e.response['Error']['Code'] == "404":
return False
else:
raise e
return True
path_exists('path/to/file.html')
s3.Client.head_object를 호출하여 ObjectSummary 자원의 속성을 업데이트하십시오.
사용 ObjectSummary
하지 Object
않을 계획이라면 대신 사용할 수 있음을 나타냅니다 get()
. 이 load()
함수는 요약 만 얻은 개체를 검색하지 않습니다.
다음은 나를 위해 작동하는 솔루션입니다. 한 가지주의 사항은 미리 키의 정확한 형식을 알고 있으므로 단일 파일 만 나열한다는 것입니다.
import boto3
# The s3 base class to interact with S3
class S3(object):
def __init__(self):
self.s3_client = boto3.client('s3')
def check_if_object_exists(self, s3_bucket, s3_key):
response = self.s3_client.list_objects(
Bucket = s3_bucket,
Prefix = s3_key
)
if 'ETag' in str(response):
return True
else:
return False
if __name__ == '__main__':
s3 = S3()
if s3.check_if_object_exists(bucket, key):
print "Found S3 object."
else:
print "No object found."
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 버킷에 파일이 있는지 여부를 확인할 수있는 간단한 방법이 있습니다. 이를 위해 예외를 사용할 필요는 없습니다.
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")
object_name
버킷으로 시작하는 파일이있는 경우 올바르지 않습니다 . 예를 들어 my_file.txt.oldversion
확인하면 가양 성이 반환됩니다 my_file.txt
. 대부분의 경우에 약간의 문제가 있지만 응용 프로그램 전체에서 사용할 가능성이 높은 "파일이 존재합니까?"
디렉토리와 동등한 키를 찾으려면이 접근법을 원할 수 있습니다
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
이것은 부모 키 또는 파일과 같은 키 또는 존재하지 않는 키에 적용됩니다. 위의 선호하는 방법을 시도했지만 부모 키에서 실패했습니다.
나는 예외를 잡기 위해 botocore.exceptions.ClientError
botocore를 설치해야한다는 것을 알았습니다. botocore는 36M의 디스크 공간을 차지합니다. aws lambda 함수를 사용하는 경우 특히 영향을 미칩니다. 그 대신 예외를 사용하면 추가 라이브러리 사용을 건너 뛸 수 있습니다!
코드는 다음과 같습니다. 당신의 생각을 공유하십시오 :
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)
에서 https://www.peterbe.com/plog/fastest-way-to-find-out-if-a-file-exists-in-s3 이 가장 빠른 방법으로 지적되고있다 :
import boto3
boto3_session = boto3.session.Session()
s3_session_client = boto3_session.client("s3")
response = s3_session_client.list_objects_v2(
Bucket=bc_df_caches_bucket, Prefix=s3_key
)
for obj in response.get("Contents", []):
if obj["Key"] == s3_key:
return True
return False
체크 아웃
bucket.get_key(
key_name,
headers=None,
version_id=None,
response_headers=None,
validate=True
)
버킷 내에 특정 키가 있는지 확인하십시오. 이 메소드는 HEAD 요청을 사용하여 키가 있는지 확인합니다. Key 객체의 인스턴스 또는 None
...에서 BOTO S3 문서
bucket.get_key (keyname)을 호출하고 반환 된 객체가 None인지 확인할 수 있습니다.