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


87

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

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


1
@pyCthon間違ったテクノロジー。再試行。
devinbost

回答:


61

S3にフォルダはありません。代わりに、キーはフラットな名前空間を形成します。ただし、名前にスラッシュが含まれるキーは、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を参照してください。botoリストキーがディレクトリキーを返す場合があります。


1
ディレクトリを削除する方法は?このディレクトリ内のすべてのファイルが削除されたときにこのディレクトリが自動的に削除される場合はどうなりますか?
wade huang 2012

ありがとう..私は〜それを終えた
黄苦労

@ wadehuang-フォルダの削除に関するコードを共有できますか?
letsc

Pythonで2日経過したs3のフォルダー内のファイルを削除する方法。これを私のs3に入れてください
-bucket

202

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

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

27
これが断然最良の答えです。
user5544 8119

2
誰かが、bucket.objects.all()。delete()が、オブジェクトの数に関係なく、バケット全体を削除せずに空にすることを知っておくと便利です(つまり、影響を受けませんが、1000アイテムの制限があります)。参照:boto3.amazonaws.com/v1/documentation/api/latest/reference/...
fabiog

1
こんにちはラズは、これはすなわち、[]、私は単純に空の角括弧を取得し、私のために働いていない
Soyf

残念ながら、これはサフィックスをサポートしていません:(
AnumSheraz20年

すばらしいのは、このソリューションが1000を超えるオブジェクトでも機能することです
Mabyn 2010

46

久しぶりだと思いますが、boto3にはこの目標を達成するためのいくつかの異なる方法があります。これは、テスト「フォルダー」とそのすべてのオブジェクトを削除することを前提としています。これは1つの方法です。

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つの要求が行われる必要があります。1つはフォルダー内のオブジェクトをフェッチし、もう1つはそのフォルダー内のすべてのオブジェクトを削除するためです。

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


これは断然最速のソリューションです。
deepelement 2016年

2
これは最速のソリューションですがlist_objects、1000を超えるキーを返すことはできないため、このコードを複数回実行する必要があることに注意してください。
lampslave 2016

4
1000を超えるオブジェクトがある場合は、paginatorを使用できます。以下の私の回答を参照してください。
dmitrybelyakov 2017

@deepelement、そしてそれboto3はボトではなく、でのみ機能します
アボカド

1
これはうまく機能し、上記のコードをlambda_handler関数に入れることでPythonラムダから実行できますimport boto3; def lambda_handler(event, context): '''Code from above'''。LambdaにS3から削除してタイムアウトを延長する許可を与えていることを確認してください。
NadirSidi18年

21

キーのリストで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)

20

パトリックのソリューションのわずかな改善。あなたが知っている、両方のかもしれませんが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)

2
そして、あなたは「ディレクトリ」を使用に制限する場合Prefixにキーワードをpaginator.paginate()参照してくださいすべてのオプション:boto3.readthedocs.io/en/latest/reference/services/...を
チャド

1
Prefix提案されたフィルタ@Chad、私は追加する必要がありましたif item is not None削除前のチェックを(私のS3プレフィックスの一部が存在していなかったので、/何のオブジェクトがありませんでした)
Y2K-shubham

3

S3バケットでバージョン管理が有効になっている場合:

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

削除されているものの出力を印刷する方法はありますか?最初にバージョンを削除してから、現在のバージョンを削除したいと思います。exbucket.objects.filter(Prefix = "myprefix /")。delete(); 現在、カーソルが点滅しているだけで、何が起こっているのかわかりません。
DJ_Stuffy_K

1
files_to_delete = bucket.object_versions.filter(Prefix="myprefix/")次に、繰り返してfiles_to_deleteprint()を呼び出し、次にdelete()を呼び出すなどの操作を行う必要があります。
ダン-devの

1

私が行ったようにオブジェクトの内容でフィルタリングする必要がある場合、以下はロジックの青写真です。

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})
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.