Redash의 동적 쿼리를 자바 스크립트에서 호출
이 동적 쿼리를 외부에서 API로, ChromeExtension에서 사용하려고 하면 도하마리했기 때문에 정리해 둡니다.
Redash의 동적 쿼리
다음과 같이 SQL 내에
{{hoge}}
라고 쓴 SQL을 지정하는 것으로 이용할 수 있습니다.SELECT account_name
FROM member
WHERE login_id = '{{login_id}}'
이러한 파라미터 첨부의 SQL을 지정하면 이하와 같은 입력란이 자동으로 생성됩니다.
사실 입력란에 값을 설정하는 것 외에도 URL의 쿼리 파라미터로 지정할 수 있습니다.
http://your.redash.host/queries/<query_id>/source?p_login_id=100
지정하는 값은
p_parameter=value
입니다. login_id
라는 매개 변수에 100을 지정하는 경우 p_login_id=100
를 URL에 추가하면됩니다.이것을 외부에서 두드릴 수 있다면 자신의 서버를 준비하지 않고 API로 사용할 수 있습니다.
라고 생각하면 일근줄로는 가지 않았습니다.
외부에서 두드리는 방법
매개변수를 사용하지 않는 쿼리라면 쿼리 편집 화면(source) 아래에서 나오는 URL을 두드리는 것만으로 JSON과 CSV로 결과를 얻을 수 있습니다.
그러나 매개 변수가있는 쿼리의 경우 동일한 방법을 사용하면 예상 결과를 얻을 수 없습니다. 적어도 매개 변수를 지정할 수 없으며 마지막으로 성공한 쿼리의 결과가 반환 동작이 된 것 같습니다.
[Feature Request] Add support for query parameters in the API
라는 issue가 존재해, Close가 되어 있었기 때문에 그것용의 API가 있을까라고 생각하면
Actually this is already possible with the refresh API. See this for example:
htps : // 기 st. 기주 b. 이 m / 예 kfr / 에 3에 434d8cfd7f331d499 ~ cf351 ~ bf9
폐쇄되었습니다. 아무래도
refresh
API를 사용해 실현할 수 있기 때문에 그것을 해라라는 것이었습니다. 의외로 이것이 귀찮습니다.싹둑 흐르게는 다음이었습니다.
query_result_id
가 돌아 오기 때문에이를 사용하여 결과 얻기 단지 파라미터 첨부의 결과를 원할 뿐인데 3회 이상 요구하지 않으면 안됩니다.
issue로 나타나고 있는 파이썬에서의 샘플나 Redash API에서 동적 쿼리를 실행하는 모듈의 흐름을 참고로, Javascript로 실행해 보았습니다.
USER Token 발급
이 절차에는 각 쿼리의
show API Key
에서 생성되는 키가 아니라 사용자별로 발급되는 API Key가 필요합니다.Settings > Users > ユーザ名 > API KEY
에서 API Key를 확인합니다.Javascript로 구현
Ajax만 할 수 있으면 좋기 때문에, jQuery등은 이용하지 않고
fetch
를 사용합니다. 물론 $.ajax
하지만 axios
하지만 같은 흐름이 된다고 생각합니다. 3회 이상 Ajax 해야 하기 때문에, 보통으로 하면 콜백 투성이로 괴롭기 때문에 async await 로 동기적으로 쓰고 있습니다.다음은 쿼리 ID : 99에
login_id
라는 매개 변수를 전달하여 실행됩니다.async function accessRedash(accountId){
const API_TOKEN = 'YOUR USER TOKEN not query token.';
// クエリパラメータ付でrefresh apiを実行
let response = await fetch('http://your.redash.host/api/queries/99/refresh?p_login_id=' + accountId, {
method: 'POST',
headers: {
'Authorization': `Key ${API_TOKEN}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}).then(res => {
return res.json();
})
// refresh apiの戻り値にはjobが入っている
let job = response['job'];
// job のステータスが3,4になるまで実行(refreshが完了すると脱出する)
while (job.status !== 3 && job.status !== 4) {
// job apiで最新のジョブの状況をチェック
response = await fetch('http://your.redash.host/api/jobs/' + job['id'], {
headers: {
'Authorization': `Key ${API_TOKEN}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}).then(res => {
return res.json();
})
job = response['job'];
// 0.5秒とりあえず待つ
await sleep(500);
}
// jobが完了している場合query_result_idが手に入る
const resultId = job['query_result_id'];
// query_result_id で指定される結果をJSONで受け取る(.jsonと指定することでJSON形式になる)
response = await fetch(`http://your.redash.host/api/queries/99/results/${resultId}.json`,{
headers: {
'Authorization': `Key ${API_TOKEN}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}).then(res => {
return res.json();
})
// query_result.dataに配列で結果が格納されているので後は好きにする
const resultSet = response.query_result.data;
console.log(resultSet)
}
// sleep helper
function sleep(msec){
return new Promise(resolve => setTimeout(resolve, msec));
}
async await로 편하게 걸겠습니다만, 솔직하게 쓰고 있으면 몹시 중첩이 깊어져 힘들었을 것이다라고 생각합니다. Redash 3.0에서 시도했지만 어쨌든이 근처의 문서가 적어서 고생했기 때문에 Qiita에게 기사로 남겨 드리겠습니다.
Reference
이 문제에 관하여(Redash의 동적 쿼리를 자바 스크립트에서 호출), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/denzow/items/2d5c43a7120a8fbf673d텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)