2012-07-11 34 views
26

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".Amazon S3 boto - cách xóa thư mục?

Bây giờ tôi muốn sử dụng boto để xóa thư mục "kiểm tra".

Tôi nên làm gì?

+0

chỉ là một dự đoán sẽ không rm -r việc/thử nghiệm? – pyCthon

Trả lời

33

không có thư mục trong S3. Thay vào đó, các phím 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ụ Amazon S3 boto - how to create a folder?).

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 khác về trang này 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, tức là, nếu không có dấu gạch chéo được nối, chương trình cũng sẽ xóa một cách hạnh phúc your/directory-that-you-wanted-to-remove-is-definitely-not-t‌​his-one.

Để biết thêm thông tin, xem S3 boto list keys sometimes returns directory key.

+0

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

+0

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

+0

@wadehuang - bạn có thể chia sẻ mã của bạn về việc xóa thư mục không? – letsc

16

Bạn có thể sử dụng bucket.delete_keys() với một danh sách các phím (với một số lượng lớn các phím Tôi thấy điều này như là một thứ tự cường độ nhanh hơn so với sử dụng key.delete).

Something 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) 
+0

Xem giải pháp của Patrick để tránh các yêu cầu N + 1 – deepelement

23

Tôi cảm thấy rằng nó được một lúc và boto3 có một vài cách khác nhau để hoàn thành mục tiêu này. Điều này giả định bạn muốn xóa kiểm tra "thư mục" 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) 

này nên thực hiện hai yêu cầu, một để lấy các đối tượng trong thư mục, 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

+0

Đây là giải pháp nhanh nhất hiện nay. – deepelement

+0

Đây là giải pháp nhanh nhất, nhưng hãy nhớ rằng 'list_objects' không thể trả về hơn 1000 khóa, do đó bạn cần chạy mã này nhiều lần. – lampslave

+1

Bạn có thể sử dụng trình tạo trang nếu bạn có nhiều hơn 1k đối tượng - xem câu trả lời của tôi bên dưới. – dmitrybelyakov

6

Một cải thiện nhỏ về giải pháp của Patrick. Như bạn có thể biết, cả hai số list_objects()delete_objects() đều có giới hạn đối tượng là 1000. Đây là lý do bạn phải phân trang danh sách và xóa theo khối. Điều này là khá phổ biến và bạn có thể cho Prefix-paginator.paginate() để xóa các thư mục con/đường dẫn

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) 
Các vấn đề liên quan