1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AthenaのSaved Queriesをコンソール以外から取得する

Posted at

はじめに

AWSアカウントをクローズする際にAthenaのバックアップを行ったのがきっかけです。
コンソール上でSaved Queriesをまとめて取得する方法が見つからず、またS3に保存されているわけでも無さそうだったため、備忘録として試した内容を以下にまとめます。

Saved Queries

何度も使うクエリに名前と説明を付けて保存しておく機能です。
ワークグループごとに分けて保存できます。
saved_queries.png

取得方法

以下の2つの方法でSaved Queriesを取得します。

  • AWS CLI
  • AWS SDK for Python

実行環境

  • macOS High Sierra 10.13.6
  • aws-cli 1.16.128
  • Python 3.6.8
  • botocore 1.15.46

~/.aws/credentialsにprofileの設定がされていることが前提です。

AWS CLIを使う方法

公式のドキュメントを参考にしました。

クエリのIDリスト取得

コンソール上からは分かりませんが、各クエリにはIDが付与されています。
クエリを取得するにはこのIDが必要なため、まずはlist-named-queriesコマンドを使ってIDのリストを取得します。

コマンド
aws athena list-named-queries --work-group primary --profile default
実行結果
{
    "NamedQueryIds": [
        "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    ]
}

クエリの取得

get-named-queryコマンドでIDを指定してクエリを取得します。

コマンド
aws athena get-named-query --named-query-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx --profile default
実行結果
{
    "NamedQuery": {
        "Name": "test query",
        "Description": "test saved query",
        "Database": "test_database",
        "QueryString": "SELECT * FROM \"test_database\".\"test_table\" limit 10",
        "NamedQueryId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "WorkGroup": "primary"
    }
}

一度に複数のクエリを取得することはできないため、全てのクエリを取得するにはIDの数だけコマンドを実行する必要があります。

AWS SDK for Python (boto3)を使う方法

基本的な流れはAWS CLIの場合と同じです。
Boto3のドキュメントを参考にしました。

クエリのIDリスト取得

list_named_queries関数でIDリストを取得します。

import os
import json
import boto3
import time

from boto3.session import Session
profile = 'default'
session = Session(profile_name=profile)
athena = session.client('athena','ap-northeast-1')

#IDのリスト取得
saved_query_list = athena.list_named_queries(
    WorkGroup='primary',
    MaxResults=50
)

レスポンスの内容について

基本的ににはAWS CLIと同様のJSON形式で返却されます。

レスポンス形式
{
    'NamedQueryIds': [
        'string',
    ],
    'NextToken': 'string'
}

AWS CLIの場合との違いはNextTokenです。
AWS SDKで一度に取得できるIDの数はリクエストで指定したMaxResultsの値(最大50)となり、保存されているクエリの数がそれより多い場合はレスポンスにNextTokenがセットされています。

IDリストの続きを取得

51個目以降(リクエストでMaxResults=50を設定した場合)のIDリストを取得するには、NextTokenを設定して再度リクエストを行います。

next_saved_query_list = athena.list_named_queries(
    WorkGroup='primary',
    MaxResults=50,
    NextToken=saved_query_list['NextToken']
)

更にIDリストが続く場合は同様のリクエストを繰り返します。

クエリの取得

get_named_query関数にIDを指定してクエリを取得します。

saved_query = athena.get_named_query(
    NamedQueryId=saved_query_list['NamedQueryIds'][0]
)

AWS CLIの場合と同様の形式でクエリが返却されます。

レスポンス形式
{
    'NamedQuery': {
        'Name': 'string',
        'Description': 'string',
        'Database': 'string',
        'QueryString': 'string',
        'NamedQueryId': 'string',
        'WorkGroup': 'string'
    }
}

全てのクエリを取得するにはIDの数だけget_named_query関数を実行します。

全てのクエリを取得

IDリストの取得、クエリの取得、保存を行うコードをまとめてみました。
ローカルディレクトリにクエリ毎にファイルを分けて保存しています。

import os
import json
import boto3
import time
from boto3.session import Session

profile = 'default'
session = Session(profile_name=profile)
athena = session.client('athena','ap-northeast-1')

# IDリスト取得
query_id_list = []
nextToken = ''
while True:
    if nextToken == '':
        saved_query_list = athena.list_named_queries(
            WorkGroup='primary',
            MaxResults=50
        )
    else:
        saved_query_list = athena.list_named_queries(
            WorkGroup='primary',
            MaxResults=50,
            NextToken=nextToken
        )
        
    tmp_query_id_list = saved_query_list['NamedQueryIds']
    for query_id in tmp_query_id_list:
        query_id_list.append(query_id)

    if 'NextToken' in saved_query_list.keys():    #50件以上ある場合
        nextToken = saved_query_list['NextToken']
        time.sleep(1)
    else:
        nextToken=''
        break

print('query num:',len(query_id_list))

# クエリ取得&保存
for query_id in query_id_list:
    filename = './query/' + query_id + '.json'
    # 取得
    query = athena.get_named_query(
        NamedQueryId=query_id
    )
    # 保存
    with open(filename, mode='w') as outfile:
        outfile.write(json.dumps(query))    
    time.sleep(1)

今回は試していませんが、create_named_query関数を使えば別のワークグループやAWSアカウントへのクエリの保存もできると思います。

まとめ

AWS CLIを使う方法とAWS SDKを使う方法の2つを試しました。
どちらも方法もIDリストの取得 → クエリの取得という手順を踏む必要があります。
まとめて取得したい場合や、シェルを書くことに抵抗が無い人以外はSDKを使って作業するのが良いと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?