Athena-ExpressでAmazon Athena Parameterized Queriesを実行する

2022.10.23

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 IoT事業部の若槻です。

前回のエントリAthena-Expressを使ってAmazon Athenaへのクエリの実行と結果取得を行いましたが、その際に「Athena-ExpressではParameterized Queriesを実行できるのか?」が気になったので確認してみました。(結論としては実行できました)

Athena-ExpressではExecutionParametersを指定できない

Parameterized QueriesをAPIから実行したい場合は、次のようにStartQueryExecutionExecutionParametersを指定します。

aws athena start-query-execution \
--query-string "SELECT * FROM gluedatabase.source_glue_table WHERE deviceId = ?" \
--execution-parameters "1" "2"

しかしAthena-ExpressのパラメータではStartQueryExecution APIのExecutionParametersに該当するパラメータがありません。

//StartQueryExecutionのExecutionParametersに該当するパラメータがない
let myQuery = {
    sql: "SELECT * FROM elb_logs LIMIT 3" // required,
    db: "sampledb", // optional. 
    pagination: 5, //optional
    NextToken: "ARfCDXRjMk...", //optional
    QueryExecutionId: "c274843b-4c5c-4ccf-ac8b-e33d595b927d", //optional
    catalog: "hive" //optional
};

この場合に、Athena-ExpressでParameterized Queriesを実行する方法はあるのでしょうか。

実行する方法

Parameterized Queriesを予めPrepared Statementとして作成しておき、EXECUTE ... USINGというステートメントを使用すればAthena-ExpressでもParameterized Queriesを実行することができました。

Prepared Statementの事前作成

実行したいParameterized QueriesのPrepared Statementを事前に作成しておきます。

STATEMENT_NAME=queryDevices
WORK_GROUP=workGroupVersionSpecified
QUERY_STATEMENT="SELECT * FROM gluedatabase.source_glue_table WHERE deviceId = ?"

aws athena create-prepared-statement \
--statement-name ${STATEMENT_NAME} \
--work-group ${WORK_GROUP} \
--query-statement ${QUERY_STATEMENT}

Athena-ExpressでParameterized Queriesを実行する

EXECUTE ... USINGのステートメントをAthena-Expressで実行します。

athena-express-query.ts

import { AthenaExpress } from 'athena-express';
import * as AWS from 'aws-sdk';

AWS.config.update({ region: 'ap-northeast-1' });

const athenaExpressConfig = {
  aws: AWS, //必須
  workgroup: 'workGroupVersionSpecified', //オプション。既定はdefault
};

const athenaExpress = new AthenaExpress(athenaExpressConfig);

const main = async () => {
  const sqlQuery = "EXECUTE queryDevices USING 'd001'";
  const results = await athenaExpress.query(sqlQuery);

  console.log(results);
};

main();

するとParameterized Queriesのクエリを実行でき、結果を取得することができました。

$ npx ts-node athena-express-query.ts 
{
  Items: [
    {
      deviceid: 'd001',
      maxtemperature: 19.8,
      year: 2022,
      month: 10,
      day: 30
    },
    {
      deviceid: 'd001',
      maxtemperature: 22.7,
      year: 2022,
      month: 10,
      day: 15
    },
    {
      deviceid: 'd001',
      maxtemperature: 19.8,
      year: 2022,
      month: 11,
      day: 1
    },
    {
      deviceid: 'd001',
      maxtemperature: 19.1,
      year: 2022,
      month: 10,
      day: 1
    }
  ]
}

おわりに

Athena-ExpressでAmazon Athena Parameterized Queriesを実行してみました。

前回のエントリでお伝えしたとおり、Athena-Expressを使うとAmazon Athenaへのクエリの実行と結果取得をシンプルにすることができます。Parameterized Queriesを使用すると予めクエリの内容のパターンが決まっているクエリの呼び出しをさらにシンプルにすることができ、またSQLインジェクション対策にもなります。Prepared Statementを事前作成しておく必要はありますが、Parameterized QueriesをAthena-Expressでも使えるのは両者のいいところ取りができて助かりますね。

参考

以上