Amazon S3 boto - klasör nasıl silinir?


87

S3'te "test" adlı bir klasör oluşturdum ve "test_1.jpg", "test_2.jpg" yi "test" e ittim.

"Test" klasörünü silmek için boto'yu nasıl kullanabilirim?


1
@pyCthon Yanlış teknoloji. Tekrar deneyin.
devinbost

Yanıtlar:


61

Orada hiçbir S3 klasörleri. Bunun yerine, anahtarlar düz bir ad alanı oluşturur. Bununla birlikte, adında eğik çizgi bulunan bir anahtar, AWS konsolu dahil olmak üzere bazı programlarda özel olarak gösterilir (örneğin Amazon S3 boto - nasıl klasör oluşturulur? )

"Bir dizini" silmek yerine, dosyaları öneklere göre listeleyebilir ve silebilirsiniz (ve yapmanız gerekir). Özünde:

for key in bucket.list(prefix='your/directory/'):
    key.delete()

Ancak bu sayfadaki diğer başarılı cevaplar daha verimli yaklaşımlar içermektedir.


Önekin sadece kukla dize araması kullanılarak arandığına dikkat edin. Ön ek olsaydı your/directory, yani sondaki eğik çizgi eklenmemişse, program da mutlu bir şekilde silerdi your/directory-that-you-wanted-to-remove-is-definitely-not-t‌​his-one.

Daha fazla bilgi için bkz.S3 boto liste tuşları bazen dizin anahtarı döndürür.


1
Dizin nasıl silinir? Bu dizindeki tüm dosyalar silindiğinde bu dizin otomatik olarak silinecekse?
wade huang

Teşekkür ederim ..
Bitirdim

@wadehuang - klasör silme ile ilgili kodunuzu paylaşır mısınız?
letsc

Python'da 2 günlük s3 klasöründeki dosyalar nasıl silinir. bunu
s3'ümde var

202

İşte 2018 (neredeyse 2019) versiyonu:

s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
bucket.objects.filter(Prefix="myprefix/").delete()

27
Bu açık ara en iyi cevap.
user554481

2
Biri, kova.objects.all (). delete () 'ın, kaç nesne olursa olsun (yani etkilenmez ancak 1000 öğe sınırı) tüm paketi silmeden boşalttığını bilmek faydalı olabilir. Bakınız: boto3.amazonaws.com/v1/documentation/api/latest/reference/…
fabiog

1
Merhaba Raz bu benim için çalışmıyor, sadece boş köşeli parantezler
alıyorum

Maalesef bu, Soneki desteklemiyor :(
Anum Sheraz

Harika bir şey bu çözüm daha da 1000'den nesnelerle çalışır olmasıdır
Mabyn

46

Uzun zaman oldu ve boto3'ün bu hedefe ulaşmak için birkaç farklı yolu olduğunu hissediyorum. Bu, test "klasörünü" ve tüm nesnelerini silmek istediğinizi varsayar. İşte bir yol:

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)

Bu, biri klasördeki nesneleri getirmek, ikincisi ise söz konusu klasördeki tüm nesneleri silmek için iki istekte bulunmalıdır.

https://boto3.readthedocs.org/en/latest/reference/services/s3.html#S3.Client.delete_objects


Bu, açık ara en hızlı çözümdür.
deepelement

2
Bu en hızlı çözümdür, ancak list_objects1000'den fazla anahtarı döndüremeyeceğini ve bu kodu birden çok kez çalıştırmanız gerektiğini unutmayın.
lightslave

4
1k'den fazla nesneniz varsa paginator'ı kullanabilirsiniz - aşağıdaki cevabıma bakın.
dmitrybelyakov

@deepelement ve yalnızca çalışır boto3değil boto,
avokado

1
Bu harika çalışıyor ve bir lambda_handler işlevinde yukarıdaki kodu koyarak bir Python lambda çalıştırabilirsiniz: import boto3; def lambda_handler(event, context): '''Code from above'''. Lambda'nıza S3'ten silme ve zaman aşımını uzatma izni verdiğinizden emin olun.
Nadir Sidi

21

Kova.delete_keys () 'i bir anahtar listesi ile kullanabilirsiniz ( çok sayıda anahtarla, bunu key.delete kullanmaktan daha büyük bir sıra olarak buldum).

Bunun gibi bir şey:

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)

20

Patrick'in çözümünde küçük bir gelişme. Bilirsiniz, hem edebileceğiniz gibi list_objects()ve delete_objects()1000'de bir nesne sınırı İlanınızı paginate ve topaklar halinde silmek zorunda nedeni budur. Bu oldukça evrenseldir ve verebilir Prefixüzere paginator.paginate()silme altdizinler / yollara

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)

2
Eğer bir "dizinine" için limitin istiyorlarsa kullanmak Prefixanahtar kelime paginator.paginate()See tüm seçenekleri: boto3.readthedocs.io/en/latest/reference/services/...
Çad

1
@ChadPrefix tarafından önerilen filtre ile, silmedenif item is not None önce bir kontrol eklemem gerekiyordu (S3 öneklerimden bazıları mevcut olmadığından / hiçbir nesneye sahip olmadığından)
y2k-shubham

3

S3 klasöründe sürüm oluşturma etkinse:

s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
bucket.object_versions.filter(Prefix="myprefix/").delete()

Silinenlerin bir kısmını yazdırmanın bir yolu var mı? Önce sürümleri, sonra mevcut sürümü silmek istiyorum. ex kova.objects.filter (Prefix = "myprefix /"). delete (); şu anda sadece yanıp sönen bir imleç görüyorum ve ne olduğunu bilmiyorum.
DJ_Stuffy_K

1
Daha files_to_delete = bucket.object_versions.filter(Prefix="myprefix/")sonra yinelemek files_to_deleteve print (), sonra delete () çağırmak gibi bir şey yapmanız gerekir.
Dan-Dev

1

Benim yaptığım gibi nesne içeriklerine göre filtrelemeye ihtiyaç duyulursa, aşağıdaki mantık için bir plandır:

def get_s3_objects_batches(s3: S3Client, **base_kwargs):
    kwargs = dict(MaxKeys=1000, **base_kwargs)
    while True:
        response = s3.list_objects_v2(**kwargs)
        # to yield each and every file: yield from response.get('Contents', [])
        yield response.get('Contents', [])
        if not response.get('IsTruncated'):  # At the end of the list?
            break
        continuation_token = response.get('NextContinuationToken')
        kwargs['ContinuationToken'] = continuation_token


def your_filter(b):
   raise NotImplementedError()


session = boto3.session.Session(profile_name=profile_name)
s3client = session.client('s3')
for batch in get_s3_objects_batches(s3client, Bucket=bucket_name, Prefix=prefix):
    to_delete = [{'Key': obj['Key']} for obj in batch if your_filter(obj)]
    if to_delete:
        s3client.delete_objects(Bucket=bucket_name, Delete={'Objects': to_delete})
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.