##やりたいこと
S3 Selectを使用してS3のファイルにSQLクエリで検索をかけて必要なレコードを取得したい。
##嬉しいこと
- S3のファイルから対象データをサクッと調べたいときに便利。
- クエリ検索するにはデータベースに入れる必要があったが、それが不要になる。
- API GatewayやLambdaなどと組み合わせることによって、S3のデータに対してのサーバーレスなアプリケーションを構築できる。
##S3 Selectのポイント
- S3上の1ファイルを対象にしている。
- ファイル形式はCSV、JSON、Apache Parquet形式に対応している。
- GZIP、BZIP2の圧縮形式に対応している。
- AWS SDKやAWS CLIからのSQLクエリにも対応している。
- 料金は「スキャンしたデータ量+返却したデータ量」での課金となるため、対象となるファイルは圧縮しておいた方がよさげ。
S3のコンソール画面から操作してみる
今回は以下の形式のサンプルファイルをS3に配置して検証します。
male 14 student
female 26 employee
male 32 selfemployed
male 45 unemployed
female 11 student
male 24 employee
male 33 selfemployed
male 49 unemployed
female 57 unemployed
S3のコンソール画面から対象のファイルを選択し、S3 Selectのタブを選択。
ファイル形式:CSV
区切り文字:タブ
圧縮:なし
「次へ」
実行したいSQLを入力します。
1カラム目が「female」のレコード取得したいと思います。
select * from s3object s where s._1 = 'female'
ちゃんと取得できました。
「ダウンロード」をするとCSVファイルとしてダウンロードできます。
EC2インスタンスからPythonでSQLクエリを実行する
EC2インスタンスからPythonでSQLクエリを実行するパターンも試してみます。
まずは、必要となるPythonのインストールを行います。
# Python3をインストール
$ sudo yum update -y
$ sudo yum install python3 -y
# 仮想環境の有効化
$ python3 -m venv ~/s3select_example/env
$ source ~/s3select_example/env/bin/activate
# boto3をインストール
$ pip install pip --upgrade
$ pip install boto3
次にPythonファイルを作成します。
import boto3
s3 = boto3.client('s3')
resp = s3.select_object_content(
Bucket='my-bucket.01',
Key='sample/sample.tsv',
ExpressionType='SQL',
Expression="SELECT * FROM s3object s where s._1 = 'female'",
InputSerialization = {'CSV': {"FileHeaderInfo": "NONE", 'FieldDelimiter': '\t'}, 'CompressionType': 'NONE'},
OutputSerialization = {'CSV': {}},
)
for event in resp['Payload']:
if 'Records' in event:
records = event['Records']['Payload'].decode('utf-8')
print(records)
BucketとKeyはS3の読み込むファイルに合わせてください。
あと、今回の対象ファイルがタブ区切りなので、InputSerializationのFieldDelimiterには「'\t'」を指定しています。
それでは実行してみましょう。
$ python S3Select.py
female,26,employee
female,11,student
female,57,unemployed
コンソール画面から実行した結果と同じレコードが出力されました!
今回は、S3のファイルをSQLクエリで直接検索して、対象のレコードを取ってくることを行いました。
S3のファイルに対して調査を行うことがあったりするので、機会があれば使っていきたいと思います。