はじめに
AWSアカウントをクローズする際にAthenaのバックアップを行ったのがきっかけです。
コンソール上でSaved Queriesをまとめて取得する方法が見つからず、またS3に保存されているわけでも無さそうだったため、備忘録として試した内容を以下にまとめます。
Saved Queries
何度も使うクエリに名前と説明を付けて保存しておく機能です。
ワークグループごとに分けて保存できます。
取得方法
以下の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を使って作業するのが良いと思います。