aws-sdk-goを使ってAthenaの実行結果を取得する
別の記事で、aws-sdk-goからAthenaのクエリを実行しました。
その際結果取得はaws-sdk-goのathena使わずに、s3経由でDLしちゃったほうがいいと書いたんですが、やはり使おうかなと思ったので、メモ代わりに簡単な解説とサンプルを残しておきます。
前提
aws-sdk-go (1.12.44)
GetQueryResults
公式ドキュメントの通り、GetQueryResultsInputを作って呼び出します。
最大取得件数を設定できて、かつページングが実行できるためなかなか便利です。
GetQueryResultsInput(引数のstruct)
QueryExecutionId
, NextToken
, MaxResults
を設定します。
NextToken
に前回のAPI呼び出しで返却されたtokenを渡すと、自動でページングして次の結果をMaxResults
分返却してくれます。
GetQueryResultsOutput(返り値のstruct)
NextToken
, ResultSet
が含まれます。
ResultSet
は前回の記事で記載したとおり、なかなか厄介な形になっています。
type ResultSet struct {
// The metadata that describes the column structure and data types of a table
// of query results.
ResultSetMetadata *ResultSetMetadata `type:"structure"`
// The rows in the table.
Rows []*Row `type:"list"`
// contains filtered or unexported fields
}
type Row struct {
// The data that populates a row in a query result table.
Data []*Datum `type:"list"`
// contains filtered or unexported fields
}
type Datum struct {
// The value of the datum.
VarCharValue *string `type:"string"`
// contains filtered or unexported fields
}
下記のような関係です。
struct | property | 中身 |
---|---|---|
ResultSet | Rows: []Row | CSVのカラム数 x MaxResults分のデータ |
Row | Data: []Datum | 1行分のデータ |
Datum | VarCharValue: *string | 1カラムのデータ |
注意点
1.Datumがnilの場合がある
下記のように、[]string
に入れ替えようとするとpanic起こす場合があります。
// rowはRow
sl := make([]string, len(row.Data))
for i, val := range row.Data {
sl[i] = *va.VarCharValue
}
sl := make([]string, len(row.Data))
for i, val := range row.Data {
if val == nil || val.VarCharValue == nil {
sl[i] = ""
} else {
sl[i] = *val.VarCharValue
}
}
2.一番最初のレスポンスの一行目がheaderになる
tokenなしでの初回リクエスト時、最初のRowはCSVのheaderが返ってきます。
https://stackoverflow.com/questions/45075754/amazon-athena-how-to-store-results-after-querying-with-skipping-column-headers
将来的にはきっとAPIのパラメータで制御できるようになるはず、、
サンプルまとめ
packageの全体は前記事を参照してください。
var GetAthenaQueryResult = func(id *string, token *string, hits int64) ([][]string, *string, error) {
input := &athena.GetQueryResultsInput{
QueryExecutionId: id,
NextToken: token,
MaxResults: &hits,
}
output, err := athenaClient.GetQueryResults(input)
if err != nil {
return nil, nil, err
}
ret := make([][]string, hits)
index := 0
for i, row := range output.ResultSet.Rows {
if i == 0 && token == nil {
// tokenなし(初回)リクエストの場合、
// csvのheaderが最初に返ってくるため無視する
continue
}
line := make([]string, len(row.Data))
for j, val := range row.Data {
if val == nil || val.VarCharValue == nil {
line[j] = ""
} else {
line[j] = *val.VarCharValue
}
}
ret[index] = line
index++
}
return ret, output.NextToken, nil
}
呼び出し元はこんな感じです。
var rows [][]string
var token *string
var err error
queryId := "hogehoge"
hits := 100
for {
rows, token, err = client.GetAthenaQueryResult(&queryId, token, hits)
if err != nil {
return err
}
fmt.Println(rows)
// dataがもうなければ終了
if token == nil {
return nil
}
}
Author And Source
この問題について(aws-sdk-goを使ってAthenaの実行結果を取得する), 我々は、より多くの情報をここで見つけました https://qiita.com/chisso/items/0e25b7fe683d6f51aa60著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .