Amazon S3 boto - làm thế nào để xóa thư mục?


87

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"?


1
@pyCthon Công nghệ sai. Thử lại.
devinbost

Câu trả lời:


61

Không 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à your/directory, 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-that-you-wanted-to-remove-is-definitely-not-t‌​his-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.


1
Làm thế nào để xóa thư mục? Nếu thư mục này sẽ tự động bị xóa khi tất cả các tệp trong thư mục này bị xóa?
wade huang,

Cảm ơn bạn .. Tôi đã hoàn thành nó ~
lội huang

@wadehuang - bạn có thể chia sẻ mã của mình về cách xóa các thư mục không?
letc

Cách xóa các tập tin trong thư mục s3 có 2 ngày tuổi trong python. có cái này trong s3 - bucket / 1 / backup / (10 tệp) của tôi cần phải xóa tất cả các tệp đã cũ hai ngày
艾瑪艾瑪

190

Đâ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()

23
Đây là câu trả lời tốt nhất cho đến nay.
user554481

1
ai đó có thể thấy hữu ích khi biết rằng bucket.objects.all (). delete () xóa toàn bộ nhóm mà không xóa nó, bất kể có bao nhiêu đối tượng (tức là nó không bị ảnh hưởng nhưng giới hạn 1000 mục). Xem: boto3.amazonaws.com/v1/documentation/api/latest/reference/…
fabiog

1
Hi Raz đây không phải đang làm việc cho tôi, tôi chỉ đơn giản là có được dấu ngoặc vuông trống, tức là []
Soyf

Đáng buồn thay, điều này không hỗ trợ Hậu tố :(
Anum Sheraz

Điều tuyệt vời là giải pháp này hoạt động ngay cả với hơn 1000 đối tượng
Mabyn

45

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


Đây là giải pháp nhanh nhất.
deepelement

2
Đây là giải pháp nhanh nhất, nhưng hãy nhớ rằng list_objectskhô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.
đèn trang trí

4
Bạn có thể sử dụng paginator nếu bạn có hơn 1k đối tượng - hãy xem câu trả lời của tôi bên dưới.
dmitrybelyakov

@deepelement, và nó chỉ hoạt động trong boto3, không boto

1
Đây hoạt động tuyệt vời, và bạn có thể chạy nó từ một lambda Python bằng cách đặt các mã trên trong một hàm lambda_handler: 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ờ.
Nadir Sidi

21

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)

20

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()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)

2
Và nếu bạn muốn giới hạn trong một "thư mục", hãy sử dụng Prefixtừ khóa trong paginator.paginate()Xem tất cả tùy chọn: boto3.readthedocs.io/en/latest/reference/services/…
Chad

1
với Prefixbộ lọc được đề xuất bởi @Chad , tôi đã có thêm một if item is not Nonekiể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)
Y2K-Shubham

1

Nếu lập phiên bản được bật trên thùng S3:

s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
bucket.object_versions.filter(Prefix="myprefix/").delete()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.