Amazon Redshift でcliから複数のクエリを投げてみた


Amazon Redshiftで複数クエリを投げる時にめちゃくちゃ苦労したので、まとめてみる。
利用環境はMacです。
前回の記事に引き続いて検証しました〜!

【背景】

  • Athenaで複数のクエリを投げてみました(こちらご参照ください)が、Redshiftも同じ感じで出来そう?
  • 出来るなら検証しちゃった方がいいしやってみよう!!

こんな課題感で手を動かし始めました。

【実際にやったこと/考えていたこと】

  • cliからクエリ投げられる方法を探す
    • 全然見つからない💦
  • rubyのgemを使ってみる
    • 何使ったらいけるのかわかりにくい!!
    • 英語のドキュメントでわかりにくい!!

結局二つ目のgemで複数クエリ投げることができましたので、詰まった一つ目と一緒にまとめていきたいと思います〜!
(会社の先輩にとても助けていただきました🙇‍♂️)

cliからクエリを投げられる方法を探す

公式ドキュメントを参考にcliからawsに接続する方法を色々と探していました。
クラスターの削除や、追加については書いてあるものの、DBを立てて、クエリを投げるとこまで書いてありませんでした。

JSONでスクリプト書いてcurlで送れるだろ〜。どっかにサンプルコード書いてるだろ〜と思っていたので、なかなか調べても出てこなく、どんどん沼にはまっていった気がします。。。

ここで、先輩に一度相談して、"Gemでいいのあると思うから調べてみて〜"とのこと。
全く、考えになかったですが、"Gem redshift"と検索すると何件がヒットしました。そこで"aws-sdk-redshift"というのを見つけました。

rubyのgemを使ってみる

こちらの記事を参考にやってみてました〜!

まずaws-sdkをインストールする

日本語の参考ドキュメントの通り進めていくと(少し違いますが)、まず以下のスクリプトでレスポンスが返ってきました。
ここまででエラーが出たら、クラスターが作成できているか、必要なIAMがアタッチされているかどうかなどこちらの記事を参考にデバックしてみてください。

Redshiftとの接続
require 'aws-sdk'

cluster_identifier = "クラスター識別子"

aws_client = AWS::Redshift.client.new(
        :redshift_endpoint => "エンドポイント",
        :access_key_id => 'xxxxxxxxxxxx',
        :secret_access_key => 'xxxxxxxxxxxxxxx'
)

cluster = aws_client.describe_clusters(
                :cluster_identifier => cluster_identifier
).clusters[0]


dbuser=cluster.master_username
dburl="DBI:Pg:dbname=#{cluster.db_name};host=#{cluster.endpoint.address};port=#{cluster.endpoint.port}"

puts dbuser
puts dburl

よし!じゃあこのまま、クエリを投げよう!!!!(......どうやって???)
となりました。

あまり意味もわからないまま、認証はできた。
あまり意味もわからないが、DBも接続できた??
あまり意味もわからないから、クエリを投げるメソッドがあるのかわからない。。。

となっていました。

aws_client.methods

で、しらみつぶしにメソッド名を見て行ってもそれらしきメソッドもなく、(api_requestsがそれか!!と思いましたが、うまくできませんでした。)

ここでもう一度先輩に聞きに行くことに、、、、
すると"RedshiftDataAPIServiceってのあるけどこれは??"とのこと、、、
なんで気がつかなかったんだ!!

RedshiftDataAPIService見たら、execute_statementとかget_statement_resultある

そこからは早かったです。
先ほどのスクリプトを以下のように書き換えました。

クラスターのdbに対してクエリを投げる
require 'aws-sdk'

aws_client =  Aws::RedshiftDataAPIService::Client.new(
        access_key_id: '********************',
        secret_access_key: '************************',
      )
10.times do |i|
  aws_client.execute_statement({
    cluster_identifier: 'クラスター識別子',
    database: 'DB名',
    db_user: 'マスターユーザー名',
    sql: 'select * from db.table名'
   })
end

すると、、、何の音沙汰もない、、、、
そりゃそうです。これはクエリを投げるためのメソッド。
management consoleに見に行ったら、クエリが実行されてました。

ちなみに、レスポンスも返ってきてます。↓公式ドキュメント参照

ここで返ってきてるidを取得して、get_statement_resultでクエリの結果も確認することができます〜!!
※レスポンスをparseして、表示するところまで一つのスクリプトで書きたかったのですが、ここはまだ出来ていません。。。
今後やっていきたいと思います!!

まとめ

  • athenaでやった通り進めたらいけると思っていたら、全然方向性が違ったので、大変だった
  • 詰まったときに何で詰まっているのか、何のためにしているのかを明確にすると、方向転換ができる

英語のドキュメントが多く、日本語が少なくて大変だったので、まとめます
引き続き学びがあれば更新していきたいと思います〜:)