この記事はRedash Advent Calendar 2017 8日目の記事です。
独自のQuery Runnerを作る
いきなり元ネタを出しますが、Redashの開発者Arikさんによる、以下の投稿を見るとだいたい作り方の雰囲気がわかってきます。
上記の記事を参考に、クエリの代わりに文字列を貼り付けると、その文字列をCSVのようにパースして結果を返すような、ちょっと変わったQuery Runnerを作成します。
開発環境
細かい開発環境構築方法の説明は割愛しますので、ご了承ください。
以下の公式ドキュメントに開発環境の構築手順が記載されているため、この手順に沿って、Docker上の開発環境が整っていることを前提に進めます。
Docker Based Developer Installation Guide · Redash Help Center
なお、使用しているRedashのバージョンは master ブランチの以下のコミット時点のもので、v4.x系に該当するものだと思います。
サンプルコード
以下のスクリプトを redash/query_runner/csv_parser.py として保存します。
import csv as csv
import json
from redash.query_runner import BaseQueryRunner, register
class CsvParser(BaseQueryRunner):
@classmethod
def configuration_schema(cls):
return {
'type': 'object',
'properties': {
'delimiter': {
'type': 'string',
'title': 'Delimiter'
}
}
}
@classmethod
def annotate_query(cls):
return False
def __init__(self, configuration):
super(CsvParser, self).__init__(configuration)
def test_connection(self):
pass
def run_query(self, query, user):
data = {
'columns': [],
'rows': [],
}
delimiter = str(self.configuration.get('delimiter'))
for row in csv.DictReader(query.strip().splitlines(), delimiter=delimiter):
if len(data['columns']) == 0:
for key in row.keys():
data['columns'].append({'name': key, 'friendly_name': key})
data['rows'].append(row)
return json.dumps(data), None
register(CsvParser)
コードの詳細は割愛しますが、クエリ文字列をCSVとしてパースし、Redashのクエリ結果の形式に準拠した形に整形します。
CSVの1行目はヘッダーとして扱うようにしています。
区切り文字はデータソースの設定として定義できるようになっており、デフォルトは,(半角カンマ)としています。
本来はカラムには string などの型を明示することも可能ですが、このスクリプトでは省略しています。
docker-compose.ymlの変更
独自のQuery Runnerを使用するため、 docker-compose.yml を編集します。
以下は docker-compose.yml の差分になります。
diff --git a/docker-compose.yml b/docker-compose.yml index 536dd446..2f948d90 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,6 +17,7 @@ services: REDASH_LOG_LEVEL: "INFO" REDASH_REDIS_URL: "redis://redis:6379/0" REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres" + REDASH_ADDITIONAL_QUERY_RUNNERS: "redash.query_runner.csv_parser" worker: build: . command: scheduler @@ -31,6 +32,7 @@ services: REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres" QUEUES: "queries,scheduled_queries,celery" WORKERS_COUNT: 2 + REDASH_ADDITIONAL_QUERY_RUNNERS: "redash.query_runner.csv_parser" redis: image: redis:3.0-alpine restart: always
環境変数 REDASH_ADDITIONAL_QUERY_RUNNERS で追加のQuery Runnerを指定できます。環境変数についてはAdvent Calendar 2日目の記事がとても参考になるのでおすすめです。
ここまでで独自Query Runnerを使うための準備は完了です。
動作確認
早速、 docker-compose up して動作確認します。
データベースの作成や管理ユーザの作成については済んでいるものとして進めます。
データソースの作成
データソースの作成画面でTypeのプルダウンをクリックすると、以下のように CsvParser が追加されています。
CsvParser を選択すると、以下のようなフォームが表示されます。
データソース名は CSV として、区切り文字はデフォルトで , となっているので、あえて :(半角コロン)にしてデータソースを保存します。
クエリの実行
クエリの作成画面に移動し、データソースとして CSV を選択ます。
クエリには以下のような半角コロン区切りの文字列を入力します。
name:ring_name:finishing_move:born_on Kanji Inoki:Antonio Inoki:Enzuigiri:1943-02-20 Baba Shohei:Giant Baba:Big boot:1938-01-23
テストデータの内容については特に触れず、実行してみます。
ここまでの手順に問題がなければ、上のように文字列をパースしてクエリ結果として表示することができます。
カラムの並び順が入力したものと違っているのは、PythonのDictが挿入順を保持しないからでしょうか。Redashは現時点でPython2.7を使用していますが、Python3.6あたりで順序が保持されるようになるので、Python3対応されたら少し結果が変わると思います。
1日目の記事で私が紹介した Query Results データソースで別の結果と結合することもできたりして面白いかもしれませんね。
まとめ
この記事ではあまり実用性を考えずに独自のQuery Runnerを作成しましたが、Redashをチームや事業にフィットするようにカスタマイズしたいと考えられる場合、Query Runnerを作るというのは選択肢にいれてみてはいかがでしょうか。
明日は take4_k さんの「azure table storageのquery runner作ってみたので書きます」です。この記事がいい前振りになることを願っています。