web-dev-qa-db-ja.com

boto3を使用してS3のファイルをオンザフライで抽出する方法は?

S3で.gzファイルをその場で抽出する方法を見つけようとしています。ローカルにダウンロードし、抽出してからS3にプッシュする必要はありません。

Boto3 + lambdaで、どのように目標を達成できますか?

Boto3ドキュメントに抽出部分がありませんでした。

7
The One

Amazon S3はストレージサービスです。ファイルのコンテンツを操作する組み込みの機能はありません。

ただし、AWS Lambda関数を使用してS3からオブジェクトを取得し、それを解凍してから、コンテンツを再度アップロードできます。ただし、Lambdaの一時ディスク領域には500MBの制限があるため、大量のデータを解凍しないようにしてください。

バケットに新しいファイルが作成されたときにLambda関数をトリガーするようにS3バケットを設定できます。 Lambda関数は次​​のことを行います。

  • Boto3(Pythonが好きだと仮定)を使用して新しいファイルをダウンロードします
  • zipfile Pythonライブラリを使用してファイルを抽出します
  • Boto3を使用して、結果のファイルをアップロードします

サンプルコード

import boto3

s3 = boto3.client('s3', use_ssl=False)
s3.upload_fileobj(
    Fileobj=gzip.GzipFile(
        None,
        'rb',
        fileobj=BytesIO(
            s3.get_object(Bucket=bucket, Key=gzip_key)['Body'].read())),
    Bucket=bucket,
    Key=uncompressed_key)
4
John Rotenstein

BytesIOを使用してS3からファイルをストリーミングし、gzipで実行し、upload_fileobjを使用してS3にパイプで戻し、BytesIOを書き込むことができます。

# python imports
import boto3
from io import BytesIO
import gzip

# setup constants
bucket = '<bucket_name>'
gzipped_key = '<key_name.gz>'
uncompressed_key = '<key_name>'

# initialize s3 client, this is dependent upon your aws config being done 
s3 = boto3.client('s3', use_ssl=False)  # optional
s3.upload_fileobj(                      # upload a new obj to s3
    Fileobj=gzip.GzipFile(              # read in the output of gzip -d
        None,                           # just return output as BytesIO
        'rb',                           # read binary
        fileobj=BytesIO(s3.get_object(Bucket=bucket, Key=gzipped_key)['Body'].read())),
    Bucket=bucket,                      # target bucket, writing to
    Key=uncompressed_key)               # target key, writing to

キーが正しく読み込まれていることを確認してください:

# read the body of the s3 key object into a string to ensure download
s = s3.get_object(Bucket=bucket, Key=gzip_key)['Body'].read()
print(len(s))  # check to ensure some data was returned
7
Todd Jones