Eu criei uma pasta no s3 chamada "test" e coloquei "test_1.jpg", "test_2.jpg" em "test".
Como posso usar o boto para deletar a pasta "teste"?
Eu criei uma pasta no s3 chamada "test" e coloquei "test_1.jpg", "test_2.jpg" em "test".
Como posso usar o boto para deletar a pasta "teste"?
Respostas:
Não há pastas no S3. Em vez disso, as chaves formam um namespace simples. No entanto, uma chave com barras em seu nome é exibida especialmente em alguns programas, incluindo o console AWS (consulte por exemplo Amazon S3 boto - como criar uma pasta? ).
Em vez de excluir "um diretório", você pode (e deve) listar arquivos por prefixo e excluir. Em essência:
for key in bucket.list(prefix='your/directory/'):
key.delete()
No entanto, as outras respostas concluídas nesta página apresentam abordagens mais eficientes.
Observe que o prefixo é pesquisado apenas usando a pesquisa de string fictícia. Se o prefixo fosse , ou seja, sem a barra final anexada, o programa também o excluiria your/directory
your/directory-that-you-wanted-to-remove-is-definitely-not-this-one
.
Para obter mais informações, consulte S3 boto list keys às vezes retorna a chave de diretório.
Aqui está a versão 2018 (quase 2019):
s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
bucket.objects.filter(Prefix="myprefix/").delete()
Eu sinto que já faz um tempo e o boto3 tem algumas maneiras diferentes de atingir esse objetivo. Isso pressupõe que você deseja excluir a "pasta" de teste e todos os seus objetos. Aqui está uma maneira:
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)
Isso deve fazer duas solicitações, uma para buscar os objetos da pasta e a segunda para excluir todos os objetos dessa pasta.
https://boto3.readthedocs.org/en/latest/reference/services/s3.html#S3.Client.delete_objects
list_objects
não pode retornar mais de 1000 chaves, portanto, você precisa executar esse código várias vezes.
boto3
, não boto
import boto3; def lambda_handler(event, context): '''Code from above'''
. Certifique-se de dar permissão ao seu Lambda para excluir do S3 e estender o tempo limite.
Você pode usar bucket.delete_keys () com uma lista de chaves (com um grande número de chaves, achei isso uma ordem de magnitude mais rápido do que usar key.delete).
Algo assim:
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)
Uma ligeira melhora na solução de Patrick. Como você deve saber, ambos list_objects()
e delete_objects()
têm um limite de objeto de 1000. É por isso que você deve paginar a listagem e excluir em pedaços. Isso é muito universal e você pode dar Prefix
para paginator.paginate()
a subdiretórios apagar / caminhos
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
palavra - chave em paginator.paginate()
Ver todas as opções: boto3.readthedocs.io/en/latest/reference/services/…
Prefix
filtro sugerido por @Chad , eu tive que adicionar uma if item is not None
verificação antes da exclusão (já que alguns dos meus prefixos S3 não existiam / não tinham objetos)