web-dev-qa-db-ja.com

Amazon S3 boto-フォルダーを削除する方法

「test」という名前のs3にフォルダーを作成し、「test_1.jpg」、「test_2.jpg」を「test」にプッシュしました。

Botoを使用してフォルダー「test」を削除するにはどうすればよいですか?

48
wade huang

S3にはnoフォルダーがあります。代わりに、キーはフラットな名前空間を形成します。ただし、名前にスラッシュが含まれるキーは、AWSコンソールを含む一部のプログラムで特別に表示されます(例: Amazon S3 boto-フォルダーの作成方法? )。

「ディレクトリ」を削除する代わりに、プレフィックスと削除によってファイルを一覧表示できます(リストする必要があります)。本質的に:

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

ただし、このページの他の回答は、より効率的なアプローチを特徴としています。


プレフィックスはダミー文字列検索を使用して検索されることに注意してください。プレフィックスが your/directory、つまり、末尾のスラッシュが付加されていない場合、プログラムはyour/directory-that-you-wanted-to-remove-is-definitely-not-t‌​his-one

詳細については、 S3ボトリストキーがディレクトリキーを返すことがあるを参照してください。

46
Antti Haapala

これは2018(ほぼ2019)バージョンです:

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

しばらくして、boto3にはこの目標を達成するためのいくつかの異なる方法があると感じています。これは、test「folder」とそのすべてのオブジェクトを削除することを前提としています。

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)

これにより、フォルダ内のオブジェクトを取得する要求と、フォルダ内のすべてのオブジェクトを削除する要求の2つの要求が行われます。

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

41
Patrick

キーのリストで bucket.delete_keys() を使用できます(多数のキーがある場合、これはkey.deleteを使用するよりも1桁高速であることがわかりました)。

このようなもの:

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)
19
David Fooks

パトリックのソリューションのわずかな改善。ご存知かもしれませんが、list_objects()delete_objects()のオブジェクト制限は1000です。これが、リストをページ分割して削除する必要がある理由です。これはかなり普遍的であり、Prefixpaginator.paginate()に与えてサブディレクトリ/パスを削除できます。

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)
17
dmitrybelyakov