Tôi đã tạo một thư mục trong s3 có tên là "test" và tôi đã đẩy "test_1.jpg", "test_2.jpg" vào "test".
Làm thế nào tôi có thể sử dụng boto để xóa thư mục "kiểm tra"?
Câu trả lời:
Không có thư mục nào trong S3. Thay vào đó, các khóa tạo thành một không gian tên phẳng. Tuy nhiên, một khóa có dấu gạch chéo trong tên của nó hiển thị đặc biệt trong một số chương trình, bao gồm bảng điều khiển AWS (xem ví dụ: boto Amazon S3 - cách tạo thư mục? ).
Thay vì xóa "một thư mục", bạn có thể (và phải) liệt kê các tệp theo tiền tố và xóa. Về bản chất:
for key in bucket.list(prefix='your/directory/'):
key.delete()
Tuy nhiên, các câu trả lời hoàn thành khác trên trang này có các cách tiếp cận hiệu quả hơn.
Lưu ý rằng tiền tố chỉ được tìm kiếm bằng cách sử dụng tìm kiếm chuỗi giả. Nếu tiền tố là , nghĩa là, không có dấu gạch chéo ở cuối được thêm vào, chương trình cũng sẽ vui vẻ xóa your/directory
your/directory-that-you-wanted-to-remove-is-definitely-not-this-one
.
Để biết thêm thông tin, hãy xem Các khóa danh sách boto của S3 đôi khi trả về khóa thư mục.
Đây là phiên bản 2018 (gần như 2019):
s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
bucket.objects.filter(Prefix="myprefix/").delete()
Tôi cảm thấy rằng đã được một thời gian và boto3 có một số cách khác nhau để hoàn thành mục tiêu này. Điều này giả sử bạn muốn xóa "thư mục" thử nghiệm và tất cả các đối tượng của nó Đây là một cách:
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)
Thao tác này sẽ thực hiện hai yêu cầu, một yêu cầu tìm nạp các đối tượng trong thư mục, yêu cầu thứ hai để xóa tất cả các đối tượng trong thư mục đã nói.
https://boto3.readthedocs.org/en/latest/reference/services/s3.html#S3.Client.delete_objects
list_objects
không thể trả về hơn 1000 khóa, vì vậy bạn cần chạy mã này nhiều lần.
boto3
, không boto
import boto3; def lambda_handler(event, context): '''Code from above'''
. Đảm bảo rằng bạn cấp cho Lambda quyền xóa khỏi S3 và kéo dài thời gian chờ.
Bạn có thể sử dụng bucket.delete_keys () với một danh sách các khóa (với một số lượng lớn các khóa, tôi thấy đây là thứ tự cấp độ nhanh hơn so với sử dụng key.delete).
Một cái gì đó như thế này:
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)
Một chút cải tiến về giải pháp của Patrick. Như bạn có thể biết, cả hai list_objects()
và delete_objects()
đều có giới hạn đối tượng là 1000. Đây là lý do tại sao bạn phải phân trang danh sách và xóa theo từng phần. Điều này là khá phổ biến và bạn có thể cho Prefix
để paginator.paginate()
đến thư mục con delete / đường
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
từ khóa trong paginator.paginate()
Xem tất cả tùy chọn: boto3.readthedocs.io/en/latest/reference/services/…
Prefix
bộ lọc được đề xuất bởi @Chad , tôi đã có thêm một if item is not None
kiểm tra trước khi xóa (vì một số tiền tố S3 của tôi không tồn tại / không có đối tượng)