Как я могу легко определить, существует ли ресурс корзины Boto 3 S3?

Например, у меня есть этот код:

import boto3

s3 = boto3.resource('s3')

bucket = s3.Bucket('my-bucket-name')

# Does it exist???

person Daniel    schedule 11.11.2014    source источник


Ответы (6)


На момент написания этой статьи не существовало высокоуровневого способа быстро проверить, существует ли сегмент и есть ли у вас доступ к нему, но вы можете выполнить низкоуровневый вызов операции HeadBucket. Это самый недорогой способ сделать эту проверку:

from botocore.client import ClientError

try:
    s3.meta.client.head_bucket(Bucket=bucket.name)
except ClientError:
    # The bucket does not exist or you have no access.

Кроме того, вы также можете повторно вызывать create_bucket. Операция является идемпотентной, поэтому она либо создаст, либо просто вернет существующее ведро, что полезно, если вы проверяете существование, чтобы узнать, следует ли вам создавать ведро:

bucket = s3.create_bucket(Bucket='my-bucket-name')

Как всегда, обязательно ознакомьтесь с официальной документацией.

Примечание. До выпуска 0.0.7 meta был словарем Python.

person Daniel    schedule 11.11.2014
comment
это также лучший метод для проверки существования объектов, для вызова head_object() и обработки ошибки? в отличие от key in bucket.objects.all()? (особенно если вы не собираетесь на самом деле get() объект?) - person Christopher Pearson; 24.07.2015
comment
@ChristopherPearson обычно лучше использовать head_object(), потому что он будет выполнять только один небольшой запрос, в то время как использование bucket.objects.all() будет извлекать всю информацию об объекте (что может быть несколько запросов для каждой страницы результатов), а затем ищет наличие вашего ключа в эти результаты. - person Daniel; 28.07.2015
comment
Небольшое уточнение: create_bucket() возвращает ошибку BucketAlreadyOwnedByYou во всех регионах AWS, кроме региона Восток США (Северная Вирджиния), а в регионе us-east-1 вы получите 200 OK. Использование head_object() на самом деле является правильным способом. - person lec00q; 07.04.2017
comment
К сожалению, вызов create_bucket для существующей корзины, созданной в другом регионе, вызовет следующее исключение: ClientError: An error occurred (BucketAlreadyOwnedByYou) when calling the CreateBucket operation: Your previous request to create the named bucket succeeded and you already own it. - person siesta; 19.05.2017
comment
Прямая ссылка на документацию: boto3.readthedocs.io/ ru/последнее/руководство/ - person Cjkjvfnby; 05.09.2017

Как упоминал @Daniel, лучший способ, предложенный документами Boto3, — использовать head_bucket()

head_bucket(). Эта операция полезна, чтобы определить, существует ли сегмент и есть ли у вас разрешение на доступ к нему.

Если у вас небольшое количество ведер, можно использовать следующее:

>>> import boto3
>>> s3 = boto3.resource('s3')
>>> s3.Bucket('Hello') in s3.buckets.all()
False
>>> s3.Bucket('some-docs') in s3.buckets.all()
True
>>> 
person helloV    schedule 11.11.2014
comment
Да, это сработает, если вы являетесь владельцем корзины, однако она вызовет операцию ListBuckets, которая немного дороже, чем операция HeadBucket. Для небольших объемов вызовов это будет стоить столько же, но если вы проверяете много сегментов, со временем они могут возрасти! Кроме того, коллекция создает экземпляры ресурсов после анализа ответа, в то время как вызов head_bucket просто возвращает низкоуровневый ответ без дополнительной обработки. - person Daniel; 13.11.2014

Я добился успеха с этим:

import boto3

s3 = boto3.resource('s3')
bucket = s3.Bucket('my-bucket-name')

if bucket.creation_date:
   print("The bucket exists")
else:
   print("The bucket does not exist")
person href_    schedule 13.04.2018
comment
Это лучшее решение IMO, потому что: 1) оно не требует ListBuckets, которые могут быть дорогими; 2) не требует перехода к низкоуровневому клиентскому API - person Oliver; 07.02.2019
comment
@ciastek, ты упустил суть. @ Оливер имел в виду, что вам, как программисту, не нужно напрямую использовать низкоуровневый клиент для выполнения этого действия. Конечно, внутренне он может сделать вызов, но это невидимо для программиста. Пожалуйста, вернитесь и перечитайте вопрос и ответ. - person Urda; 19.06.2019

Я попробовал пример Даниэля, и это было действительно полезно. Просмотрел документацию boto3 и вот мой чистый тестовый код. Я добавил проверку на ошибку «403», когда ведра являются частными и возвращают «Запрещено!» ошибка.

import boto3, botocore
s3 = boto3.resource('s3')
bucket_name = 'some-private-bucket'
#bucket_name = 'bucket-to-check'

bucket = s3.Bucket(bucket_name)
def check_bucket(bucket):
    try:
        s3.meta.client.head_bucket(Bucket=bucket_name)
        print("Bucket Exists!")
        return True
    except botocore.exceptions.ClientError as e:
        # If a client error is thrown, then check that it was a 404 error.
        # If it was a 404 error, then the bucket does not exist.
        error_code = int(e.response['Error']['Code'])
        if error_code == 403:
            print("Private Bucket. Forbidden Access!")
            return True
        elif error_code == 404:
            print("Bucket Does Not Exist!")
            return False

check_bucket(bucket)

Надеюсь, это поможет некоторым новичкам в boto3, таким как я.

person mondnom    schedule 30.11.2017

Использовать функцию поиска -> Возвращает None, если ведро существует

if s3.lookup(bucketName) is None:
    bucket=s3.create_bucket(bucketName) # Bucket Don't Exist
else:
    bucket = s3.get_bucket(bucketName) #Bucket Exist
person Jacob Oommen    schedule 18.01.2017
comment
Нет функции поиска в клиенте s3 boto3 или ресурсном API. - person Atifm; 09.02.2017

вы можете использовать conn.get_bucket

from boto.s3.connection import S3Connection
from boto.exception import S3ResponseError    

conn = S3Connection(aws_access_key, aws_secret_key)

try:
    bucket = conn.get_bucket(unique_bucket_name, validate=True)
except S3ResponseError:
    bucket = conn.create_bucket(unique_bucket_name)

цитирование документации по адресу http://boto.readthedocs.org/en/latest/s3_tut.html

Начиная с Boto v2.25.0, он теперь выполняет запрос HEAD (менее затратный, но хуже сообщения об ошибках).

person vim    schedule 01.07.2015
comment
это не для бото не бото3? - person Christopher Pearson; 28.07.2015