のべラボ.blog

Tech Blog | AWS や サーバーレスやコンテナ などなど

Amazon Athena を AWS CLI から使用してみる

今回は、AWS CLI を使って Amazon Athena のデータベースとテーブル、ワークグループを作成し、クエリーを発行してみます。

標準 SQL を使用して Amazon S3バケット内のデータに対して直接クエリーを発行して集計や分析が行えるインタラクティブなサービスです。

aws.amazon.com

AWS マネジメントコンソールを使用して容易に操作することもできますが、AWS CLI だとどのようなコマンドになるのか試してみます。

なお、この記事の内容は 下記のドキュメントを参考に、2023年 1月に検証した内容に基づいています。LinuxAWS CLI v2 を使用する前提とします。

awscli.amazonaws.com


Amazon Athena には ワークグループ というグルーピングの概念があり、ワークグループ単位で処理できるデータ量や Amazon CloudWatch のメトリクスの設定などを行えます。

docs.aws.amazon.com

デフォルトでも primary というワークグループがあり、それを使用できますが今回は新たにワークグループ my-workgroup を作成する前提とします。

まず、ワークグループで発行したクエリ結果を保存するための Amazon S3バケットとフォルダをあらかじめ作成しておきます。

ここでは、バケット tnobe-datalake-athena-result のフォルダ my-workgroup とします。

次に AWS CLI でワークグループ my-workgroup を作成します。

# ワークグループの作成
aws athena create-work-group \
    --name my-workgroup \
    --configuration ResultConfiguration={OutputLocation="s3://tnobe-datalake-athena-result/my-workgroup/"} \
    --description "demo workgroup" 

今回は、クエリーの結果の保存先以外の設定はデフォルトのままにしています。

ワークグループの作成を確認するため、次の AWS CLI コマンドを発行します。

# ワークグループの一覧表示
aws athena list-work-groups

下記のように、primary の他に my-workgroup が表示されていれば OK です。

{
    "WorkGroups": [
        {
            "Name": "my-workgroup",
            "State": "ENABLED",
            "Description": "demo workgroup",
            "CreationTime": "2023-01-09T03:12:47.798000+00:00",
            "EngineVersion": {
                "SelectedEngineVersion": "AUTO",
                "EffectiveEngineVersion": "Athena engine version 2"
            }
        },
        {
            "Name": "primary",
            "State": "ENABLED",
            "Description": "",
            "CreationTime": "2022-12-22T23:20:09.520000+00:00",
            "EngineVersion": {
                "SelectedEngineVersion": "AUTO",
                "EffectiveEngineVersion": "Athena engine version 2"
            }
        }
    ]
}

では次に データベースを作成します。今回は mydatabase という名前にします。

# データベースの作成
aws athena start-query-execution \
    --query-string "CREATE SCHEMA mydatabase" \
    --work-group "my-workgroup" 

作成したデータベースを確認します。

# データベースの一覧表示
aws athena list-databases  --catalog-name AwsDataCatalog

環境によっては複数のデータベースが表示されますが、下記のように mydatabase が表示されれば OK です。

{
   "Name": "mydatabase"
}

ここであることに気づきました。

AWS マネジメントコンソールにて、Amazon Athena のクエリエディタからデータベースを作成する場合は、次のコマンドで作成できます。

CREATE DATABASE mydatabase

しかし、AWS CLI の start-query-execution コマンドを使用して上記データベースを作成する SQL を発行すると、次のようなエラーが発生します。

An error occurred (InvalidRequestException) when calling the StartQueryExecution operation: line 1:8: mismatched input 'database'. Expecting: 'OR', 'SCHEMA', 'TABLE', 'VIEW'

つまり、CREATE DATABASE が使えないという事ですね。

しかし、次のドキュメントに、CREATE DATABASECREATE SCHEMA と同じでどちらでも使用できると記載されています。

docs.aws.amazon.com

よって今回は CREATE SCHEMA を使用しました。

また、データベースの名前を my-database のように ハイフン (-) を含んだ名前にすると次のようなエラーになります。

An error occurred (InvalidRequestException) when calling the StartQueryExecution operation: line 1:17: mismatched input '-'. Expecting: '.', 'WITH', <EOF>

これも AWS マネジメントコンソールでは発生しないエラーなので、少しハマってしまいました。

このように、AWS CLI ならではの書き方が必要なケースがあるので、注意が必要です。


データベースが作成できたら、次はテーブルを作成します。

今回は、Amazon Athena のチュートリアル用として公開されている CloudFrontへのアクセスログデータを使用します。

# テーブルの作成
aws athena start-query-execution \
    --query-string  \
 "CREATE EXTERNAL TABLE IF NOT EXISTS cloudfront_logs (   \
  LogDate DATE,                                           \
  Time STRING,                                            \
  Location STRING,                                        \
  Bytes INT,                                              \
  RequestIP STRING,                                       \
  Method STRING,                                          \
  Host STRING,                                            \
  Uri STRING,                                             \
  Status INT,                                             \
  Referrer STRING,                                        \
  ClientInfo STRING                                       \
  )                                                       \
  ROW FORMAT DELIMITED                                    \
  FIELDS TERMINATED BY '\t'                               \
  LINES TERMINATED BY '\n'                                \
  LOCATION 's3://athena-examples-ap-northeast-1/cloudfront/plaintext/'" \
    --query-execution-context Database=mydatabase

テーブルを作成したら、さっそくクエリーを発行してみます。

aws athena start-query-execution \
    --query-string "select logdate, location, uri, status from cloudfront_logs where method = 'GET' and status = 200 and location like 'SFO%' limit 10" \
    --work-group "my-workgroup" \
    --query-execution-context Database=mydatabase

クエリーを発行すると次のような ID 値が返されるので、メモしておきます。

{
    "QueryExecutionId": "0df4e7c9-b9f7-46cf-92f0-42344cdfce23"
}

この ID 値を指定して、クエリーの結果を取得します。

aws athena get-query-results \
    --query-execution-id 0df4e7c9-b9f7-46cf-92f0-42344cdfce23

次のように、カラム名とクエリーの結果が表示されれば OK です。

{
    "ResultSet": {
        "Rows": [
            {
                "Data": [
                    {
                        "VarCharValue": "logdate"
                    },
                    {
                        "VarCharValue": "location"
                    },
                    {
                        "VarCharValue": "uri"
                    },
                    {
                        "VarCharValue": "status"
                    }
                ]
            },
            {
                "Data": [
                    {
                        "VarCharValue": "2014-07-05"
                    },
                    {
                        "VarCharValue": "SFO4"
                    },
                    {
                        "VarCharValue": "/test-image-2.jpeg"
                    },
                    {
                        "VarCharValue": "200"
                    }
                ]
            },
    {
                "Data": [
                    {
                        "VarCharValue": "2014-07-05"
                    },
                    {
                        "VarCharValue": "SFO4"
                    },
                    {
                        "VarCharValue": "/test-image-2.jpeg"
                    },
                    {
                        "VarCharValue": "200"
                    }
                ]
            },
・・・(以下略)・・・

最後に

AWS CLI ならではの書き方のところは要注意ですが、コマンドの種類もそんなに多くなく、パラメータの書き方もさほど複雑ではないので思いのほかシンプルに記述できた、というのが感想です!

/* -----codeの行番号----- */