CircleCIのスケジュールで定期的にredashからcsvをダウンロードしようとしてちょっとハマりました。
redashのAPIガイドを見ると/api/queries/<id>/results.csv
に{"max_age":0}
をPOSTすれば最新情報への更新とダウンロードを同時にできそうに見えたけどできなかった。。。
当初InternalServerErrorが帰ってきたので、redashのバグかと思ったけど色々試して起こっていることを推測できたのでここに記しておきます。
ポイント: URLを /results.csv
から /results
に変えるとエラーにならない
両者の違いは結果がcsvで返るかJSONで返るかなので、後者で実行した場合は結果は当然JSONで返ってきます。
しかし、それで返ってきたJSONはクエリ結果の情報ではなくどうやらJOBの情報っぽい。
APIガイドのrefreshのあたりを見るとrefreshするとJOBが更新されるから、query_result_idが入るのを待て、みたいなことが書いてあるからどうやら更新された結果を取得するにはここにquery_result_idが設定される(=クエリのキャッシュが作られる)のを待つ必要があるらしい。
で、URLに.csv
がついている場合にエラーになるのはおそらくJOBの情報をcsvに変換する仕組みがないからだと想像します。
ちなみにrefresh APIを実行するにはuser_api_keyが必要ですが、こちらのresults APIへのPOSTはquery_api_keyで実行できます。
なので、このPOST resultsは内部的には単純にrefresh APIを呼び出しているだけでそれをquery_api_keyで可能にするためのエイリアスなんじゃないかと思っています。
つまりスクリプトでredashから最新のcsvを取得しようとしたら、
refresh -> sleep N秒 -> results.csv
という手順を踏む必要があると思われます。
それでも良いんだけど、今回の場合はそこまでリアルタイム性が必要ではないのでクエリのrefreshはredash側でスケジュールして、CircleCIでは結果取得だけを行うことにしました。
忘れてたけど使っているRedashのバージョンは8.0です。
この結果にはredashのバージョンも関係すると思います。
最新版のredashでは別の挙動になるかもしれません。(書いた後に気がついたけど、ドキュメント通り一発でrefreshと結果取得ができる可能性も高い気がしてきました。。。)