ソースコードから理解する技術-UnderSourceCode

手を動かす(プログラムを組む)ことで技術を理解するブログ

aws cdk でAthenaのNamed Queryを作成する

AWS Athenaにはよく使うクエリを保存する Named Queryという機能があります。マネージメントコンソール上では「Saved Queries」というタブに表示されます。

今回はこのNamed Queryをaws cdkでデプロイしてみました。aws cdkを使ったのは、クエリは特に開発時は何度も変更するため、cdkを使って繰り返しデプロイできるようにしたら開発効率が上がるのではないかと思ったためです。(もちろん画面にて更新することもできますが)

Named Query以外の、データベースやテーブルなどは、今回はマネージメントコンソールから手動で作成しました。以下、今回の作業の流れとなります。

  • S3のバケットを作成し、検索元データのCSVをアップロードする。
  • Athenaの画面にてデータベースを作成する。
  • Athenaの画面にてテーブルを作成する。
  • クエリ結果の保存先「Query result location」をAthenaの画面にて作成する。
  • Named Queryをaws cdkで作成、デプロイする。

以下、それぞれについて書いていきます。

データベース作成

最初のS3のバケット作成、データのCSVのアップロードについては省きます。データのCSVを事前にS3にアップロードしておきます。
データベースについては、Athenaの「Query Editor」に以下のcreate database文を流すことで作成しました。(今回はsample_carsというデータベース名とします。センス無いですが、テーブル名も同じにしました。)

create database sample_cars;

なおデータベースを作成しないと、以下のテーブル作成で使う「Create table」のリンクが出てきませんでいた(私の作業ミスの可能性もありますが。明示的にデータベースを選ばなければならなかったのか?)

テーブル作成

Athenaの画面の左側に「Create table」というリンクがあるので、クリックします。カラム名と型を指定できるので、CSVの中から取得したい対象のカラムを指定して、画面にてテーブルを作成します。画面に表示されるCreate文は以下で使うので保存しておきます。

画面にて作成されたデフォルトの状態だと、CSVの一行目が列名を示すヘッダーとなっている場合、ヘッダーが検索結果として抽出されてしまいます。これを防ぐ為には、画面にてテーブルを作成したときに表示されたCreate文を保存しておき、「'skip.header.line.count'='1'」をプロパティに追加して再度実行します。Create文は以下のようになります。

CREATE EXTERNAL TABLE IF NOT EXISTS sample_cars.sample_cars (
  `id` int,
  (中略)
)
(中略)
TBLPROPERTIES (
  'skip.header.line.count'='1', -- これを追加
  'has_encrypted_data'='false'
);

Query result location

クエリの実行結果の保存先を「Query result location」で指定します。画面右上の「Settings」をクリックするとダイアログが出てくるので、そこで指定します。

aws cdkでNamed Queryを作成

プロジェクト作成

さて本題のNamed Queryです。aws cdkでのプロジェクト作成は、以下の公式チュートリアルや、以前書いた記事を参考にしてください。
Getting Started With the AWS CDK - AWS Cloud Development Kit (AWS CDK)
aws-cdkを触ってみた - ソースコードから理解する技術-UnderSourceCode

aws cdkのプロジェクトフォルダを作成し、以下を実行します。

$ npx cdk init app --language=typescript
$ npx cdk --version

今回はaws cdkの「aws-athena」モジュールを使うので、以下のコマンドでインストールします。

$ npm install @aws-cdk/aws-athena

cdkのプロジェクトが作成されると、「lib」フォルダ内の.tsファイルに「The code that defines your stack goes here」というコメントがあります。ここに任意の作成したいコードを記述します。今回はAthenaのNamed Queryを作成するコードを記載します。.tsファイルは以下のようになりました。

import * as cdk from '@aws-cdk/core';
import athena = require('@aws-cdk/aws-athena');

export class CdkAthenaQueryStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here
    new athena.CfnNamedQuery(this, 'MySampleCars', {
      database: 'sample_cars',
      description: 'this is a sample named query.',
      name: 'sample-cars-query',
      queryString: 'select id, maker, model, transmission_type from sample_cars.sample_cars limit 10;',
    })
  }
}

「sample_cars」データベースを指定し、「queryString」にてSelect文を定義しているのが分かるかと思います。次にこれをデプロイしてみます。

Named Queryのデプロイ

デプロイについては標準的なaws cdkの手順通りです。私は以下のコマンドで実行しました。

$ npm run build
$ npx cdk synth
$ npx cdk deploy

デプロイを実行すると、Athenaの画面の「Saved Queries」タブに、クエリが出来ているはずです。選択して実行できることを確認してみてください。

次にクエリの変更についてです。cdkの「queryString」のSelect文を変更し、以下のコマンドを実行します。

$ npm run build
$ npx cdk synth
$ npx cdk diff
$ npx cdk deploy

最初の「npm run build」を忘れると変更が反映されないので注意です。「diff」を使うと変更箇所が分かります(今回はクエリになるはずです)。デプロイして、画面からクエリを実行して結果が変わっていれば成功です。