Athena for Javascriptを使う

S3からデータを抽出できるAWS Athena(アテナと読みます)。
サービス開始当初はJavaでないと使用できなかったのですが、いつの間にかJavascript SDKが公開されています。
ブラウザから直接クエリが投げられ、サーバー側の実装が一切不要なため是非おすすめしたいサービスです。
当記事ではブラウザからクエリを投げてみるところまで、行ってみます。

 

SDKの入手

次のサイトからSDKを入手してください。
AWS SDK for JavaScript のドキュメント

AWS SDK for JavaScript ダウンロード

 

リストの中からAthenaを選んでダウンロードします。

Athenaを選んでダウンロード

 

S3にデータを用意します。

S3にデータを用意

Data1.json

{ "id": 1, "name": "name1" }
{ "id": 2, "name": "name2" }
{ "id": 3, "name": "name3" }

 

Data2.json

{ "id": 4, "name": "name4" }
{ "id": 5, "name": "name5" }

 

Athenaでテーブル定義を作ります。

Athenaでテーブル定義

 

DB名、テーブル名、S3上のKEY(フォルダ名)を設定します。
KEYは最後"/"スラッシュで終わる必要があるので注意してください。

DB名、テーブル名、S3上のKEY(フォルダ名)を設定

 

今回はJSONファイルを用意したのでJSONを選びます。

JSONファイルを選択""

 

JSONの内容に合わせて列名と型を入れます。型が違うとSQL実行時にエラーになるのできちんと設定してください。

Datebases 列名と型を入れる

 

パーティションというRDBでいう所のINDEXに近い物を設定できますが、今回はパスしておきます。

パーティション

 

これでテーブルが完成しました。

Athena for Javascript テーブルが完成

 

試しに実行してみましょう。

Athena for Javascript 実行

 

きちんとJSONの中が取れてるのが確認できました。これをHTMLから実行してみます。

 

IAMの用意

細かい手順は省きますが、"AmazonAthenaFullAccess"というポリシーがあるので、これをアタッチしたユーザーを作っておけば大丈夫です。

また、アクセスキーを作成して置いてください。あとでHTMLに埋め込みます。

IAMの用意

 

今回はアクセスキーをHTMLへ埋め込みますが、サービスを本稼働させる場合はセキュリティー上の問題があります。

AWS STSで一時キーを発行するなど、別の手段でアクセスキーの発行を検討してください。

 

HTMLの用意

いよいよHTMLからAthenaを呼び出していきます。

次のファイルを作成してください。

 

athena.html

<!doctype htm>
<html>
<head>
  <script src="aws-sdk-2.224.1.min.js"></script>
  <script>
    var athena = new AWS.Athena({
      accessKeyId: '<IAMのアクセスキーのAccess Key Id>',
      secretAccessKey: '<IAMのアクセスキーのSecret Access Key>',
      region: 'ap-northeast-1'
    });

    function startQueryExecution(callback) {
      var params = {
        QueryString: 'SELECT * FROM "xpyama"."table1" limit 10',
        ResultConfiguration: {
          OutputLocation: 's3://<バケット名>/athena/table1_result'
        }
      };
      athena.startQueryExecution(params, function(err, data) {
        if (err) {
          console.log(err);
          return;
        }
        callback(data.QueryExecutionId);
      });
    }

    function getQueryExecution(queryExecutionId, callback) {
      var params = {
        QueryExecutionId: queryExecutionId
      };
      athena.getQueryExecution(params, function(err, data) {
        if (err) {
          console.log(err);
          return;
        }
        if (data.QueryExecution.Status.State == 'RUNNING') {
          getQueryExecution(queryExecutionId, callback);
          return;
        }
        callback();
      });
    }

    function getQueryResults(queryExecutionId, callback) {
      var params = {
        QueryExecutionId: queryExecutionId
      };
      athena.getQueryResults(params, function(err, data) {
        if (err) {
          console.log(err);
          return;
        }
        callback(data);
      });
    }

    function showData(data) {
      var table = '<table>';
      for (rowNo in data.ResultSet.Rows) {
        table += '<tr>';
        for (colNo in data.ResultSet.Rows[rowNo].Data) {
          table += '<td>';
          table += data.ResultSet.Rows[rowNo].Data[colNo].VarCharValue;
          table += '</td>';
        }
        table += '</tr>';
      }
      table += '</table>';
      document.getElementsByTagName('body')[0].innerHTML = table;
    }

    startQueryExecution(function(queryExecutionId) {
      getQueryExecution(queryExecutionId, function() {
        getQueryResults(queryExecutionId, function(data) {
          showData(data);
        });
      });
    });
</script>
</head>

<body>
</body>

</html>

 

ブラウザで開くとデータが取得できることが確認できます。

Athena for Javascript データ取得

 

Javascriptの解説

19行目:startQueryExecution
AthenaでSQLを実行します。ただし結果はすぐには返って来ず、結果確認用のIDが返ってきます。

32行目:getQueryExecution
結果確認用のIDを使い、SQLが実行し終わったかどうかを確認しています。
ステータスが"RUNNING"の場合は、まだ実行中なので再び確認しに行っています。

49行目:getQueryResults
結果確認用のIDを使い、SQLの実行結果を取得しにいきます。
実行結果はstartQueryExecutionで指定したフォルダに出力されるため、いつでも取得しなおすことができます。
古い結果が不要な場合はS3のライフサイクルを設定し、実行結果ファイルごと消してやればOKです。

58行目:showData
実行結果を画面に表示しています。

いかがだったでしょうか。

1からテーブル作ってデータ作ってとやると手間はありますが、1度構築してしまえばRDBと遜色なく使用できると思います。
SQLの実行結果が再利用できる点でも、ページングの処理やシークしながら結果取得できるので便利だと思います。
もっと複雑な機能も備わっているので、その辺りは別の機会にお伝えします。

 

 

 

AWS相談会