バイセル Tech Blog

バイセル Tech Blogは株式会社BuySell Technologiesのエンジニア達が知見・発見を共有する技術ブログです。

バイセル Tech Blog

Redashのクエリ管理方法

テクノロジー開発部の村上です。 弊社ではデータ集計に一部Redashを使用しています。
そしてRedashのクエリ管理のためにmozillaが作成したredash_clientを使用してるので、
今回はその活用方法を紹介をしたいと思います。

今回ご紹介する方法のメリットは、以下の3点かなと思います。

  1. Gitでクエリを管理できる
  2. 一括でクエリ群を変更できる
  3. redash_clientを使うことで、直接REST APIを叩くより簡潔になる

ただ、Gitで管理した上で自動でRedashに反映させることも出来るはずですが、現時点ではそこまでは行っていないです。

クエリとそのメタデータの用意

まず事前に以下のようなクエリの情報を表すtsvを用意します。
queries/query_1.sqlなどに実際のクエリが書かれていることを仮定しています。

id name data_source_id path schedule description
1 クエリ1 1 queries/query_1.sql 21:00 クエリ例1
2 クエリ2 1 queries/query_2.sql 21:00 クエリ例2

Queryクラスを定義

こちらは前述したtsvの内容そのままです。

class Query:
  def __init__(self, base_path, query_id, name, data_source_id, path, schedule=None, description=''):
    self.query_id = query_id
    self.name = name
    self.data_source_id = data_source_id
    self.schedule = schedule
    self.description = description
    self.load_query(base_path, path)
    
  def load_query(self, base_path, path):
    u"""ファイルからクエリを読み込みセットする"""
    with open('{0}/{1}'.format(base_path, path), 'r') as f:
      self.query = f.read()

クエリをファイルから読み込み

読み込んだクエリをQueryクラスのインスタンスにし、queries配列を作成します。

import os.path
base_path = os.path.expanduser('~') + '/projects/redash_scripts'
import csv
reader = csv.reader(open('{0}/queries/query_list.tsv'.format(base_path), 'r'), delimiter='\t')
queries = []
header = next(reader)
for row in reader:
    queries.append(Query(base_path, row[0], row[1], row[2], row[3], row[4], row[5]))

RedashClientの作成

事前にRedashのAPIキーを取得しておき、それを使ってRedashClientを得ます。
以下のコードではredash_clientを~/projectsにcloneしていることを仮定しています。

import os
import sys

sys.path.append(os.path.expanduser('~') + '/projects/redash_client')
from redash_client.client import RedashClient

base_url = os.environ['REDASH_HOST']
api_key = os.environ['REDASH_API_KEY']
redash_client = RedashClient(api_key, base_url)

Redashに対してリクエストを送る

基本的にはredash_clientのメソッドを呼んでいるだけです。
ポイントとしては例外の処理で、クエリ中でクエリパラメータを使っていると例外が返るのでそれを無視するようにしています。

クエリ新規作成

def create_query(query):
    redash_client.create_new_query(query.name, query.query, query.data_source_id, query.description)
def create_new_queries(queries):
    u"""新規idでクエリ群を作成する"""
    for query in queries:
        print(query.query_id)
        try:
            create_query(query)
        except RedashClient.RedashClientException:
            print('Error: ' + query.query_id)            

クエリ更新

def update_query(query):
    redash_client.update_query(query.query_id, query.name, query.query, query.data_source_id, query.description)
def update_queries(queries):
    for query in queries:
        print(query.query_id)
        try:
            update_query(query)
        except RedashClient.RedashClientException:
            print('Error: ' + query.query_id)

クエリのスケジュールを設定

ここは一つ注意点がありまして、APIで登録されるのはUTCのスケジュールとなります。
なのでtsvを日本時間にした場合は、redash_clientのメソッドを呼ぶ前にUTCに変換する必要があります。
(今回は省略しています)

def set_schedules(queries):
    for query in queries:
        if not query.schedule:
            redash_client.update_query_schedule(query.query_id, query.schedule)

いかがでしょうか。
ちょっとした工夫ですが、クエリの管理工数が減らすことができました。