AWS CLI で S3 to S3 で圧縮してストリーミングコピーしたい場合は aws s3 cp s3://... - | gzip | aws s3 cp - s3://...
(S3 からローカルにファイルをまるまるダウンロードせずに圧縮して S3 にアップロードする - ablog) のようにパイプで繋げばよいが、Python で書きたい場合は smart_open
パッケージを使うとできる。
準備
- 環境
$ cat /etc/system-release Amazon Linux release 2023 (Amazon Linux) uname -r 6.1.52-71.125.amzn2023.x86_64 $ pyenv versions system 2.7.18 * 3.10.13 (set by /home/ec2-user/.pyenv/version)
- パッケージのインストール
$ pip install smart_open $ pip install boto3
- EC2 に以下の権限を持つ IAM ロールをアタッチする
- Permissions
- AmazonS3FullAccess
- Trust relationships
- Permissions
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
サンプルコード
- s3_streaming_copy.py
from smart_open import open, register_compressor import boto3 session = boto3.Session() src_path = 's3://<s3 bucket name>/sample_data/s3_streaming/1gb.dat' dst_path = 's3://<s3 bucket name>/sample_data/s3_streaming/1gb.gz' with open(dst_path, 'wb', transport_params={'client': session.client('s3')}, compression='.gz') as fout: with open(src_path, 'rb', transport_params={'client': session.client('s3')}) as fin: for s_line in fin: fout.write(s_line)
実行
- テストデータを作成して S3 にアップロードする
$ dd if=/dev/zero of=1gb.dat bs=1M count=1024 $ aws s3 cp 1gb.dat s3://<s3 bucket name>/sample_data/s3_streaming/1gb.dat $ aws s3 ls --human-readable s3://<s3 bucket name>/sample_data/s3_streaming/1gb.dat 2023-10-04 09:57:34 1.0 GiB 1gb.dat
- 実行する
$ python s3_streaming_copy.py
- 結果の確認
$ aws s3 ls --human-readable s3://<s3 bucket name>/sample_data/s3_streaming/1gb.gz 2023-10-04 09:57:56 1019.2 KiB 1gb.gz aws s3 cp s3://<s3 bucket name>/sample_data/s3_streaming/1gb.gz ./ download: s3://<s3 bucket name>/sample_data/s3_streaming/1gb.gz to ./1gb.gz $ file 1gb.gz 1gb.gz: gzip compressed data, was "1gb", last modified: Wed Oct 4 09:57:55 2023, max compression, original size modulo 2^32 1073741824