@pyCthon Неправильная технология. Попробуй еще раз.
devinbost
Ответы:
61
В S3 нет папок. Вместо этого ключи образуют плоское пространство имен. Однако в некоторых программах, в том числе в консоли AWS, клавиша с косой чертой в имени отображается специально (см., Например, Amazon S3 boto - как создать папку? ).
Вместо удаления «каталога» вы можете (и должны) перечислять файлы по префиксу и удалять. По сути:
for key in bucket.list(prefix='your/directory/'):
key.delete()
Однако в других завершенных ответах на этой странице представлены более эффективные подходы.
Обратите внимание, что префикс просто ищется с помощью поиска по фиктивной строке. Если бы префикс был your/directory, то есть без добавленной косой черты, программа также успешно удалила бы your/directory-that-you-wanted-to-remove-is-definitely-not-this-one.
Как удалить каталог? Если этот каталог будет удален автоматически при удалении всех файлов в этом каталоге?
wade huang
Спасибо .. Я закончил ~
wade huang
@wadehuang - не могли бы вы поделиться своим кодом об удалении папок?
Letc
Как удалить файлы в папке s3, которым 2 дня, в python. есть это в моем s3 - bucket / 1 / backups / (10 файлов), необходимо удалить все файлы, которым два дня назад
кому-то может быть полезно узнать, что bucket.objects.all (). delete () очищает все ведро, не удаляя его, независимо от количества объектов (т.е. это не влияет, кроме ограничения в 1000 элементов). См .: boto3.amazonaws.com/v1/documentation/api/latest/reference/…
fabiog
1
Привет, Раз, это не работает для меня, я просто получаю пустые квадратные скобки, то есть []
Soyf
К сожалению, это не поддерживает суффикс :(
Anum Sheraz
Самое замечательное, что это решение работает даже с более чем 1000 объектами
Мабин
45
Я чувствую, что прошло много времени, и у boto3 есть несколько различных способов достижения этой цели. Предполагается, что вы хотите удалить тестовую «папку» и все ее объекты. Вот один способ:
s3 = boto3.resource('s3')
objects_to_delete = s3.meta.client.list_objects(Bucket="MyBucket", Prefix="myfolder/test/")
delete_keys = {'Objects' : []}
delete_keys['Objects'] = [{'Key' : k} for k in [obj['Key'] for obj in objects_to_delete.get('Contents', [])]]
s3.meta.client.delete_objects(Bucket="MyBucket", Delete=delete_keys)
Это должно сделать два запроса: один для извлечения объектов в папке, второй для удаления всех объектов в указанной папке.
Это самое быстрое решение, но имейте в виду, что list_objectsне может вернуть более 1000 ключей, поэтому вам нужно запускать этот код несколько раз.
lamplave
4
Вы можете использовать пагинатор, если у вас более 1k объектов - см. Мой ответ ниже.
дмитрыбеляков
@deepelement, и он работает только в boto3, но не в бото
авокадо
1
Это прекрасно работает, и вы можете запустить его из лямбда Python, поставив выше код в функции lambda_handler: import boto3; def lambda_handler(event, context): '''Code from above'''. Убедитесь, что вы разрешили Lambda удалить из S3 и продлить время ожидания.
Надир Сиди
21
Вы можете использовать bucket.delete_keys () со списком ключей (я обнаружил, что с большим количеством ключей это на порядок быстрее, чем при использовании key.delete).
Что-то вроде этого:
delete_key_list = []
for key in bucket.list(prefix='/your/directory/'):
delete_key_list.append(key)
if len(delete_key_list) > 100:
bucket.delete_keys(delete_key_list)
delete_key_list = []
if len(delete_key_list) > 0:
bucket.delete_keys(delete_key_list)
Небольшое улучшение решения Патрика. Как вы, возможно, знаете, у обоих list_objects()и delete_objects()есть ограничение на количество объектов 1000. Вот почему вы должны разбивать список на страницы и удалять по частям. Это довольно универсальное и вы можете дать , Prefixчтобы paginator.paginate()удалить подкаталоги / дорожки
с Prefixфильтром, предложенным @Chad , мне пришлось добавить if item is not Noneпроверку перед удалением (поскольку некоторые из моих префиксов S3 не существовали / не имели объектов)
Ответы:
В S3 нет папок. Вместо этого ключи образуют плоское пространство имен. Однако в некоторых программах, в том числе в консоли AWS, клавиша с косой чертой в имени отображается специально (см., Например, Amazon S3 boto - как создать папку? ).
Вместо удаления «каталога» вы можете (и должны) перечислять файлы по префиксу и удалять. По сути:
for key in bucket.list(prefix='your/directory/'): key.delete()
Однако в других завершенных ответах на этой странице представлены более эффективные подходы.
Обратите внимание, что префикс просто ищется с помощью поиска по фиктивной строке. Если бы префикс был
, то есть без добавленной косой черты, программа также успешно удалила быyour/directory
your/directory-that-you-wanted-to-remove-is-definitely-not-this-one
.Дополнительные сведения см. В разделе Ключи списка загрузки S3 иногда возвращает ключ каталога.
источник
Вот версия 2018 (почти 2019):
s3 = boto3.resource('s3') bucket = s3.Bucket('mybucket') bucket.objects.filter(Prefix="myprefix/").delete()
источник
Я чувствую, что прошло много времени, и у boto3 есть несколько различных способов достижения этой цели. Предполагается, что вы хотите удалить тестовую «папку» и все ее объекты. Вот один способ:
s3 = boto3.resource('s3') objects_to_delete = s3.meta.client.list_objects(Bucket="MyBucket", Prefix="myfolder/test/") delete_keys = {'Objects' : []} delete_keys['Objects'] = [{'Key' : k} for k in [obj['Key'] for obj in objects_to_delete.get('Contents', [])]] s3.meta.client.delete_objects(Bucket="MyBucket", Delete=delete_keys)
Это должно сделать два запроса: один для извлечения объектов в папке, второй для удаления всех объектов в указанной папке.
https://boto3.readthedocs.org/en/latest/reference/services/s3.html#S3.Client.delete_objects
источник
list_objects
не может вернуть более 1000 ключей, поэтому вам нужно запускать этот код несколько раз.boto3
, но не в ботоimport boto3; def lambda_handler(event, context): '''Code from above'''
. Убедитесь, что вы разрешили Lambda удалить из S3 и продлить время ожидания.Вы можете использовать bucket.delete_keys () со списком ключей (я обнаружил, что с большим количеством ключей это на порядок быстрее, чем при использовании key.delete).
Что-то вроде этого:
delete_key_list = [] for key in bucket.list(prefix='/your/directory/'): delete_key_list.append(key) if len(delete_key_list) > 100: bucket.delete_keys(delete_key_list) delete_key_list = [] if len(delete_key_list) > 0: bucket.delete_keys(delete_key_list)
источник
Небольшое улучшение решения Патрика. Как вы, возможно, знаете, у обоих
list_objects()
иdelete_objects()
есть ограничение на количество объектов 1000. Вот почему вы должны разбивать список на страницы и удалять по частям. Это довольно универсальное и вы можете дать ,Prefix
чтобыpaginator.paginate()
удалить подкаталоги / дорожкиclient = boto3.client('s3', **credentials) paginator = client.get_paginator('list_objects_v2') pages = paginator.paginate(Bucket=self.bucket_name) delete_us = dict(Objects=[]) for item in pages.search('Contents'): delete_us['Objects'].append(dict(Key=item['Key'])) # flush once aws limit reached if len(delete_us['Objects']) >= 1000: client.delete_objects(Bucket=bucket, Delete=delete_us) delete_us = dict(Objects=[]) # flush rest if len(delete_us['Objects']): client.delete_objects(Bucket=bucket, Delete=delete_us)
источник
Prefix
ключевое слово вpaginator.paginate()
разделе «Просмотреть все параметры»: boto3.readthedocs.io/en/latest/reference/services/…Prefix
фильтром, предложенным @Chad , мне пришлось добавитьif item is not None
проверку перед удалением (поскольку некоторые из моих префиксов S3 не существовали / не имели объектов)Если управление версиями включено в сегменте S3:
s3 = boto3.resource('s3') bucket = s3.Bucket('mybucket') bucket.object_versions.filter(Prefix="myprefix/").delete()
источник