前提
- Redash 2.0.0+b2990
記事中の記法
-
<host>
はRedashのホストを意味します。たとえば、あなたの環境のRedashのGUIにアクセスする際、https://www.example.com/redash/
にアクセスしているのなら、これがホストです。<host>/api
と記載した場合、https://www.example.com/redash/api
を意味します。 - その他、
<>
で囲った文字は適宜変数を意味します。<query_id>
等
User API Keyを取得
クエリを実行
以下のURIをPOSTすると、クエリを実行できます。
<host>/api/queries/<query_id>/refresh?api_key=<user_api_key>
クエリ中にパラメータがある場合
クエリ中のパラメータはp_<parameter_name>=<value>
の形式でURLクエリパラメータとして渡します。
たとえば、
select
*
from
users
where
user_id = {{user_id}}
というクエリを、user_id=12345
で実行する場合、POSTするURIは、以下のようになります。
<host>/api/queries/<query_id>/refresh?p_user_id=12345&api_key=<user_api_key>
応答
以下のようなJSONが返ってきます。
{
"job": {
"status": 2,
"error": "",
"id": "XXXXXXXXXXX",
"query_result_id": null,
"updated_at": 0
}
}
※以降、上記のJSONのjob.id
の値を<job_id>
として扱います。
ジョブの状態を取得
以下のURIをGETするとジョブの状態を取得できます。
<host>/api/jobs/<job_id>?api_key=<user_api_key>
応答は/api/queries/<query_id>/refresh
と同じ形式です。
ジョブが終了していれば、query_result_id
に値が設定されます。
query_result_id
の値がnull
の場合は、ジョブの終了を待つ必要があります。
ジョブの結果を取得
以下のURIをGETすると、ジョブの結果が取得できます。
<host>/api/queries/<query_id>/results/<query_result_id>.json?api_key=<user_api_key>
ファイルの拡張子は.json
のほかに.csv
があります。
スニペット(GAS用)
…を踏まえたコードをGAS用に書くとこうなります。
/**
*
* @param {String} host https://redash.example.com 的なもの。末尾にスラッシュはつけないでください。
* @param {String} queryId 123等
* @param {String} apiKey
* @param {any[]} param クエリのパラメータの連想配列
*/
function callRedash(host, queryId, apiKey, param) {
let queryParams = [`api_key=${apiKey}`]
if (param) {
for (let key in param) {
const queryParam = `p_${key}=${param[key]}`;
queryParams.push(queryParam);
}
}
const refreshUri = `${host}/api/queries/${queryId}/refresh?${queryParams.join('&')}`;
const refreshResult = UrlFetchApp.fetch(refreshUri, { "method": "POST" });
const jobId = JSON.parse(refreshResult).job.id;
const jobStatusUri = `${host}/api/jobs/${jobId}?api_key=${apiKey}`;
let queryResultId = null;
const startMills = new Date().getTime();
while (true) {
const endMills = new Date().getTime();
if (endMills - startMills > (4 * 60 * 1000)) {
// GASの実行時間上限は5分なので、4分経過した時点で中断します。
throw new Error("Redashへの問い合わせ開始から4分以上経過したため、中断します。");
}
const jobStatus = JSON.parse(UrlFetchApp.fetch(jobStatusUri)).job;
const status = jobStatus.status;
if (status === 3 || status === 4) {
queryResultId = jobStatus.query_result_id;
break; // 結果を取得できたのでbreak
}
Utilities.sleep(5000); // 5秒待機
}
const jobResultUri = `${host}/api/queries/${queryId}/results/${queryResultId}.json?api_key=${apiKey}`;
const result = JSON.parse(UrlFetchApp.fetch(jobResultUri));
return result.query_result.data.rows;
}