Tidak ada folder di S3. Sebaliknya, kunci membentuk namespace datar. Namun kunci dengan garis miring pada namanya ditampilkan secara khusus di beberapa program, termasuk konsol AWS (lihat misalnya Amazon S3 boto - bagaimana cara membuat folder? ).
Alih-alih menghapus "direktori", Anda dapat (dan harus) membuat daftar file dengan awalan dan menghapus. Intinya:
for key in bucket.list(prefix='your/directory/'):
key.delete()
Namun jawaban lain yang berhasil di halaman ini menampilkan pendekatan yang lebih efisien.
Perhatikan bahwa awalan hanya dicari menggunakan pencarian string dummy. Jika awalannya your/directory, yaitu, tanpa menambahkan garis miring, program juga akan dengan senang hati menghapusnya your/directory-that-you-wanted-to-remove-is-definitely-not-this-one.
Bagaimana cara menghapus direktori? Jika direktori ini akan dihapus secara otomatis ketika semua file di direktori ini dihapus?
mengarungi huang
Terima kasih .. Saya telah menyelesaikannya ~
wade huang
@wadehuang - dapatkah Anda membagikan kode Anda tentang menghapus folder?
maric
Cara menghapus file di folder s3 yang berumur 2 hari di python. miliki ini di s3 saya - bucket / 1 / backups / (10 file) perlu menghapus semua file yang berusia dua hari
mungkin berguna bagi seseorang untuk mengetahui bahwa bucket.objects.all (). delete () mengosongkan seluruh bucket tanpa menghapusnya, tidak peduli berapa banyak objek yang ada (yaitu tidak terpengaruh tetapi dibatasi 1000 item). Lihat: boto3.amazonaws.com/v1/documentation/api/latest/reference/…
fabiog
1
Hai Raz, ini tidak berhasil untuk saya, saya hanya mendapatkan tanda kurung siku kosong, yaitu []
Soyf
Sayangnya, ini tidak mendukung Suffix :(
Anum Sheraz
Hebatnya adalah solusi ini bekerja bahkan dengan lebih dari 1000 objek
Mabyn
46
Saya merasa sudah lama dan boto3 memiliki beberapa cara berbeda untuk mencapai tujuan ini. Ini mengasumsikan Anda ingin menghapus tes "folder" dan semua objeknya Berikut adalah salah satu caranya:
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)
Ini harus membuat dua permintaan, satu untuk mengambil objek di folder, yang kedua untuk menghapus semua objek di folder tersebut.
Ini adalah solusi tercepat, tetapi perlu diingat bahwa list_objectstidak dapat mengembalikan lebih dari 1000 kunci sehingga Anda perlu menjalankan kode ini beberapa kali.
lamplave
4
Anda dapat menggunakan paginator jika Anda memiliki lebih dari 1k objek - lihat jawaban saya di bawah.
dmitrybelyakov
@deepelement, dan itu hanya bekerja di boto3, bukan boto
alpukat
1
Ini karya besar, dan Anda dapat menjalankannya dari lambda Python dengan menempatkan kode di atas dalam fungsi lambda_handler: import boto3; def lambda_handler(event, context): '''Code from above'''. Pastikan Anda memberikan izin Lambda Anda untuk menghapus dari S3 dan memperpanjang batas waktu.
Nadir Sidi
21
Anda dapat menggunakan bucket.delete_keys () dengan daftar kunci (dengan sejumlah besar kunci, saya menemukan bahwa urutan besarnya lebih cepat daripada menggunakan key.delete).
Sesuatu seperti ini:
delete_key_list = []
for key in bucket.list(prefix='/your/directory/'):
delete_key_list.append(key)
iflen(delete_key_list) > 100:
bucket.delete_keys(delete_key_list)
delete_key_list = []
iflen(delete_key_list) > 0:
bucket.delete_keys(delete_key_list)
Sedikit perbaikan pada solusi Patrick. Seperti yang Anda ketahui, keduanya list_objects()dan delete_objects()memiliki batas objek 1000. Inilah sebabnya mengapa Anda harus membuat daftar halaman dan menghapus dalam potongan. Ini sangat universal dan Anda dapat memberikan Prefixuntuk paginator.paginate()untuk menghapus subdirektori / jalur
dengan Prefixfilter yang disarankan oleh @Chad , saya harus menambahkan tanda if item is not Nonecentang sebelum menghapus (karena beberapa prefiks S3 saya tidak ada / tidak memiliki objek)
Apakah ada cara untuk mencetak keluaran dari apa yang sedang dihapus? Saya ingin menghapus versi terlebih dahulu, lalu yang sekarang. ex bucket.objects.filter (Prefix = "myprefix /"). delete (); sekarang saya hanya melihat kursor yang berkedip dan saya tidak tahu apa yang terjadi.
DJ_Stuffy_K
1
Anda harus melakukan sesuatu seperti files_to_delete = bucket.object_versions.filter(Prefix="myprefix/")iterasi files_to_deletedan memanggil print () lalu delete () pada mereka.
Dan-Dev
1
Jika seseorang perlu memfilter berdasarkan konten objek seperti yang saya lakukan, berikut ini adalah cetak biru untuk logika Anda:
defget_s3_objects_batches(s3: S3Client, **base_kwargs):
kwargs = dict(MaxKeys=1000, **base_kwargs)
whileTrue:
response = s3.list_objects_v2(**kwargs)
# to yield each and every file: yield from response.get('Contents', [])yield response.get('Contents', [])
ifnot response.get('IsTruncated'): # At the end of the list?break
continuation_token = response.get('NextContinuationToken')
kwargs['ContinuationToken'] = continuation_token
defyour_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})
Jawaban:
Tidak ada folder di S3. Sebaliknya, kunci membentuk namespace datar. Namun kunci dengan garis miring pada namanya ditampilkan secara khusus di beberapa program, termasuk konsol AWS (lihat misalnya Amazon S3 boto - bagaimana cara membuat folder? ).
Alih-alih menghapus "direktori", Anda dapat (dan harus) membuat daftar file dengan awalan dan menghapus. Intinya:
for key in bucket.list(prefix='your/directory/'): key.delete()
Namun jawaban lain yang berhasil di halaman ini menampilkan pendekatan yang lebih efisien.
Perhatikan bahwa awalan hanya dicari menggunakan pencarian string dummy. Jika awalannya
, yaitu, tanpa menambahkan garis miring, program juga akan dengan senang hati menghapusnyayour/directory
your/directory-that-you-wanted-to-remove-is-definitely-not-this-one
.Untuk informasi selengkapnya, lihat kunci daftar boto S3 terkadang mengembalikan kunci direktori.
sumber
Ini adalah versi 2018 (hampir 2019):
s3 = boto3.resource('s3') bucket = s3.Bucket('mybucket') bucket.objects.filter(Prefix="myprefix/").delete()
sumber
Saya merasa sudah lama dan boto3 memiliki beberapa cara berbeda untuk mencapai tujuan ini. Ini mengasumsikan Anda ingin menghapus tes "folder" dan semua objeknya Berikut adalah salah satu caranya:
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)
Ini harus membuat dua permintaan, satu untuk mengambil objek di folder, yang kedua untuk menghapus semua objek di folder tersebut.
https://boto3.readthedocs.org/en/latest/reference/services/s3.html#S3.Client.delete_objects
sumber
list_objects
tidak dapat mengembalikan lebih dari 1000 kunci sehingga Anda perlu menjalankan kode ini beberapa kali.boto3
, bukan botoimport boto3; def lambda_handler(event, context): '''Code from above'''
. Pastikan Anda memberikan izin Lambda Anda untuk menghapus dari S3 dan memperpanjang batas waktu.Anda dapat menggunakan bucket.delete_keys () dengan daftar kunci (dengan sejumlah besar kunci, saya menemukan bahwa urutan besarnya lebih cepat daripada menggunakan key.delete).
Sesuatu seperti ini:
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)
sumber
Sedikit perbaikan pada solusi Patrick. Seperti yang Anda ketahui, keduanya
list_objects()
dandelete_objects()
memiliki batas objek 1000. Inilah sebabnya mengapa Anda harus membuat daftar halaman dan menghapus dalam potongan. Ini sangat universal dan Anda dapat memberikanPrefix
untukpaginator.paginate()
untuk menghapus subdirektori / jalurclient = 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)
sumber
Prefix
kata kunci dipaginator.paginate()
Lihat semua opsi: boto3.readthedocs.io/en/latest/reference/services/…Prefix
filter yang disarankan oleh @Chad , saya harus menambahkan tandaif item is not None
centang sebelum menghapus (karena beberapa prefiks S3 saya tidak ada / tidak memiliki objek)Jika pembuatan versi diaktifkan pada bucket S3:
s3 = boto3.resource('s3') bucket = s3.Bucket('mybucket') bucket.object_versions.filter(Prefix="myprefix/").delete()
sumber
files_to_delete = bucket.object_versions.filter(Prefix="myprefix/")
iterasifiles_to_delete
dan memanggil print () lalu delete () pada mereka.Jika seseorang perlu memfilter berdasarkan konten objek seperti yang saya lakukan, berikut ini adalah cetak biru untuk logika Anda:
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})
sumber