AWS S3に保存しているオブジェクトを1度に1000件削除する。


やりたいこと

 削除するオブジェクトのキー名が記載されたファイルを読み込んで、ポチッと実行するだけで、削除できるようにしたい。

方針

・削除するオブジェクトのキーがかかれたファイルを用意する。
・S3のAPI(delete_objects)を利用して、ループしながらキーを指定削除する。

参考リンク
S3の削除について
pythonのdelete_objects APIについて

やったこと

・削除するオブジェクトのキーリストを作成する。

削除するオブジェクトのキーリスト
hoge/fuga/hoge.jpg
hoge/fuga/hoge.png
hoge/hoge/hoge.gif
hoge/hoge/fuga.png
・・・
fuga/fuga/fuga.png

・削除プログラムを実行する
 delete_objectsは1度に1000件しか指定できないので、読み込んだキーリストを1000件単位のリストに再分割する。分割した単位でDELETE APIを叩き、ループ実行する。
 

削除プログラム.py

import boto3
import re
import json

MY_REGION = 'リージョン名';
MY_BUCKET = 'バケット名';

client = boto3.client('s3', region_name=MY_REGION)
request_list = []
img_path_list = ''

def split_list(l):
    for idx in range(0, len(l), 1000):
        yield l[idx:idx + 1000]

# 削除データを読み込む
with open('削除するオブジェクトのキーリスト.text') as f:
    img_path_list = f.readlines()

# データ末尾の改行を削除してリストに追加する
for path in img_path_list:
    path = path.replace('\n','')
    request_list.append({'Key': path})

# リストを1000件ごとに分ける
# devide_list = [[0,...,999],[1000,...,1999],...,[n,...,n+999]]
devide_list = list(split_list(request_list))

# DELETE APIを実行する
for key_list in devide_list:
    response = client.delete_objects(
        Bucket = MY_BUCKET,
        Delete = {
            'Objects': key_list
        }
    )

    # 削除結果を記録する
    with open('log/削除結果.txt', mode='a') as f:
        for res in response['Deleted']:
            f.write(json.dumps(res))
            f.write('\n')

・削除が成功していれば、結果は下記のようになる。

削除結果.text
{"Key": "hoge/fuga/hoge.jpg", "DeleteMarker": true, "DeleteMarkerVersionId": "hogehoge1"}
{"Key": "hoge/fuga/hoge.png", "DeleteMarker": true, "DeleteMarkerVersionId": "hogehoge2"}
{"Key": "hoge/hoge/hoge.gif", "DeleteMarker": true, "DeleteMarkerVersionId": "hogehoge3"}
{"Key": "hoge/hoge/fuga.png", "DeleteMarker": true, "DeleteMarkerVersionId": "hogehoge4"}
{"Key": "fuga/fuga/fuga.png", "DeleteMarker": true, "DeleteMarkerVersionId": "hogehoge5"}

その他

削除するリストと削除しないリストを用意して、両方のリストに存在するキーがあるか確認する
Pythonで複数のリストに共通する・しない要素とその個数を取得

2つのリストに存在する要素を表示する.py
input_urls = ''
not_delete_urls = ''

# リストデータを読み込む
with open('入力リスト.txt') as f:
    input_urls = f.readlines();

with open('削除しないリスト.txt') as f:
    not_delete_urls = f.readlines();

duplicate_urls = set(input_urls) & set(not_delete_urls)

# set型からlist型に変更する
list_duplicate_urls = list(duplicate_urls)
list_duplicate_urls.sort()

# 共通要素の件数と要素を表示する
print(len(list_duplicate_urls))
for elem in list_duplicate_urls:
    print(elem, end='')

注意事項