リンクからS3 Pre-Signed URLを発行してS3データを取得する
やったこと
- リンクをクリックするとPre-Signed URLが生成され、S3上のcsvファイルのDLが行えるようにしました。
- QuickSightのダッシュボード上に上記リンクを置き、QuickSightの制限を越える帳票のDLを行う導線を設置しました。
背景
BIでピボットテーブル、テーブルチャートを使うケースで、csv形式等でDLしたい場合があります。
しかし、大量のレコードがある場合はレンダリング速度が落ちるのでそもそも、BI上で可視化を行う際は帳票形式による大量データの可視化は避けるべきだと考えます。
それでも、一括でDLさせたいケースがある場合は、直接データをDLさせることを考えると良いと思います。
例えばRedshiftを使っている場合は、スケジュールクエリを使って、クエリ結果を定期的にS3に出力する事が可能なので、BIで作っている集計表と同一の集計を行い、S3 にアンロードするなどです。
また、BIユーザーが直接S3にアクセスできないケースも考え、ダウンロードの際は、Presigined URL を発行し、安全にデータをDLするアプローチを検討する必要があると思います。
Amazon QuickSight の場合は、テーブルチャートで可視化したデータにDLに制限があり、500MB or 100万行までのcsvダウンロードが可能となっています。
また、Snapshot Export API が公開されたので、API経由でテーブルチャートのCSVをS3にダウンロードすることが可能となったので制限の範囲内でBIの集計票からCSV DLが可能となりました。(※ ただし、ページ分割レポートのサブスクリプションが必要になるので要注意。)
詳細は こちら のブログを参照。
API経由だと制限なくDLができると良かったのですが、現状難しそうなので、今回は固定化された帳票があり、定期的にS3上の固定ファイルをアップデートしているジョブがある前提で検証を進めます。
手順
1. lambda コードを開発
以下、サンプル
import boto3
import os
import json
def lambda_handler(event, context):
s3 = boto3.client('s3')
bucket_name = 'sample-datalake-landing'
object_name = 'sample_large_csv/custom_1988_2020.csv'
expiration = 100
try:
response = s3.generate_presigned_url('get_object',
Params={'Bucket': bucket_name,
'Key': object_name},
ExpiresIn=expiration)
except ClientError as e:
return {
'body': e.response['Error']['Message']
}
return {
'Location': response
}
lambda 実行ロールには、DLさせる S3 オブジェクトへのアクセス権を付与すること。
2. API Gateway の設定
2-1. リソース作成 -> Get メソッドを作る
リソース名は任意の名前で作成する。
lambda ファンクション名に、1 で作成した lambda の名前をセット。
2-2. Method Response 設定
200 を削除し、302 を追加
Header に Location
を指定。
Content type application/json
を指定。
2-3. Integration Response 設定
200 を削除し、302 を追加
Response header に Location
を指定。
Mapping value に integration.response.body.Location
を指定
完了したら、任意にステージを作成してデプロイ。
エンドポイント URL をコピペする。
QuickSightの任意のビジュアルでリンクを作成
例えばタイトルで URL リンクを作成。
完成後
リンクをクリックすると、DLが始まる。
Discussion