やりたいこと
S3上の対象のファイルを別の場所にコピーして、そのファイルが格納されていたフォルダごと削除したいことがありました。
具体的には、AWS Glueでファイルを新規フォルダに出力した後、そのファイルをリネームして別のフォルダに移動させたかったのです。
S3を扱うboto3のコードは色々と検索でヒットしましたが、ドンピシャのものがなかったので記事にしてみます。
前提
以下がコピー元、先のURIと想定します。
少しわかりにくいですが、sampleフォルダの中にあるtest.txtを1階層上に「new_file.txt」という名前にリネームして移動します。その後、sampleフォルダは削除します。
・コピー元のファイル
s3://sample-bucket/20230121_copy_glue/sample/test.txt
・コピー先のファイル
s3://sample-bucket/20230121_copy_glue/new_file.txt
実装
これで動きました。
sample
フォルダにはファイルが1つしか入っていない前提なので、1つのファイルをコピーしたらフォルダごと削除しています。
import boto3
bucket_name = "sample-bucket"
# コピー
s3 = boto3.resource('s3')
s3.Object(bucket_name,"20230121_copy_glue/new_file.txt").copy_from(CopySource=bucket_name + "/20230121_copy_glue/sample/test.txt")
# コピー元ファイル(フォルダごと)削除
bucket = s3.Bucket(bucket_name)
bucket.objects.filter(Prefix="20230121_copy_glue/sample/").delete()
おわりに
バケット名だけだったり、プレフィックスだけだったり、両方結合したり、スラッシュが入ったり入らなかったり、S3のパス指定は面倒ですね。
今回は1ファイルだけでしたが、s3の指定フォルダの中身の一覧を取得してコピーをfor文で実行、そして最後にフォルダごと削除すれば複数ファイルでもできると思います。