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 your/directory, ou seja, sem a barra final anexada, o programa também o excluiria your/directory-that-you-wanted-to-remove-is-definitely-not-this-one.
Como deletar o diretório? Se este diretório for excluído automaticamente quando todos os arquivos neste diretório forem excluídos?
wade huang
Obrigado .. Eu terminei ~
wade huang
@wadehuang - você poderia compartilhar seu código sobre exclusão de pastas?
letc
Como deletar arquivos na pasta de s3 que têm 2 dias em python. tenho isso em meu s3 - bucket / 1 / backups / (10 arquivos) preciso remover todos os arquivos que têm dois dias
alguém pode achar útil saber que bucket.objects.all (). delete () esvazia todo o bucket sem excluí-lo, não importa quantos objetos existam (ou seja, não é afetado, mas o limite de 1000 itens). Consulte: boto3.amazonaws.com/v1/documentation/api/latest/reference/…
fabiog
1
Olá, Raz, isso não está funcionando para mim. Simplesmente recebo colchetes vazios, ou seja, []
Soyf
Infelizmente, isso não é compatível com o sufixo :(
Anum Sheraz
O bom é que essa solução funciona mesmo com mais de 1000 objetos
Mabyn
45
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.
Essa é a solução mais rápida, mas lembre-se de que list_objectsnão pode retornar mais de 1000 chaves, portanto, você precisa executar esse código várias vezes.
lampião de
4
Você pode usar o paginator se tiver mais de 1k objetos - veja minha resposta abaixo.
dmitrybelyakov
@deepelement, e só funciona em boto3, não boto
abacate
1
Isso funciona muito bem, e você pode executá-lo a partir de um lambda Python, colocando o código acima em uma função lambda_handler: 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.
Nadir Sidi
21
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 Prefixpara paginator.paginate()a subdiretórios apagar / caminhos
com o Prefixfiltro sugerido por @Chad , eu tive que adicionar uma if item is not Noneverificação antes da exclusão (já que alguns dos meus prefixos S3 não existiam / não tinham objetos)
y2k-shubham
1
Se o controle de versão estiver habilitado no intervalo S3:
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 excluiriayour/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.
fonte
Aqui está a versão 2018 (quase 2019):
s3 = boto3.resource('s3') bucket = s3.Bucket('mybucket') bucket.objects.filter(Prefix="myprefix/").delete()
fonte
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
fonte
list_objects
não pode retornar mais de 1000 chaves, portanto, você precisa executar esse código várias vezes.boto3
, não botoimport 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)
fonte
Uma ligeira melhora na solução de Patrick. Como você deve saber, ambos
list_objects()
edelete_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 darPrefix
parapaginator.paginate()
a subdiretórios apagar / caminhosclient = 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)
fonte
Prefix
palavra - chave empaginator.paginate()
Ver todas as opções: boto3.readthedocs.io/en/latest/reference/services/…Prefix
filtro sugerido por @Chad , eu tive que adicionar umaif item is not None
verificação antes da exclusão (já que alguns dos meus prefixos S3 não existiam / não tinham objetos)Se o controle de versão estiver habilitado no intervalo S3:
s3 = boto3.resource('s3') bucket = s3.Bucket('mybucket') bucket.object_versions.filter(Prefix="myprefix/").delete()
fonte