Redash を PyCharm Community Edition でデバッグする

OS X での自分用作業メモ。

ターミナルでの作業

virtualenv で Redash 用の環境を作って、必要な Python モジュールを一通りインストールする。

$ pip2.7 install -U virtualenv
$ brew install python --with-berkeley-db4
$ brew unlink python && brew link python
$ brew install mysql
$ brew install freetds@0.91
$ brew link --force freetds@0.91
$ git clone git@github.com:getredash/redash.git
$ cd redash
$ virtualenv .venv
$ source .venv/bin/activate
$ pip install -r requirements.txt
$ pip install -r requirements_dev.txt
$ pip install -r requirements_all_ds.txt

メモ

  • pymssql のインストールが freetds@0.91 に依存している
  • celery を起動する時にエラーが出るのを brew install python --with-berkeley-db4 で解決する

参考

PostgreSQL と Redis の環境構築

docker-compose.development.yml として以下のファイルを作成。

docker-compose.production.yml から serverworkernginx を除いたものに近い。

version: '2'
services:
  redis:
    image: redis:3.0-alpine
    ports:
      - "6379:6379"
    restart: always
  postgres:
    image: postgres:9.5.6-alpine
    ports:
      - "5432:5432"
    volumes:
      - postgres:/var/lib/postgresql/data
    restart: always
volumes:
  postgres:
    driver: local

その後、以下のコマンドでコンテナを起動。

$ docker-compose -f docker-compose.developmens.yml up

Redash の設定

.env を以下のように作成する。PostgreSQL 、 Redash ともに Docker のコンテナを使うようにする。

export REDASH_LOG_LEVEL=INFO
export REDASH_REDIS_URL=redis://localhost:6379/0
export REDASH_DATABASE_URL=postgresql://postgres@localhost/postgres

次に、必要なテーブルを作成する。

$ ./bin/run ./manage.py database create_tables

次に、JavaScriptをビルドする。

$ npm install
$ npm run build

PyCharm での作業

Python Interpreter

virtualenv で作った環境の python を使うように設定する。

f:id:ariarijp:20180218212206p:plain

server の実行時設定

f:id:ariarijp:20180218212301p:plain

worker の実行時設定

f:id:ariarijp:20180218212310p:plain

serverworker環境変数

.env で設定している値を環境変数として設定しておく。

f:id:ariarijp:20180218212316p:plain

動作確認

server , workerDebug で実行すればブレークポイントを設定できる。

f:id:ariarijp:20180218213413p:plain

便利。

この記事では PyCharm Community Edition を使ったけれど、 Professional Edition であれば Docker 上の Pythonデバッグできるようなので、 Redash の場合はその方がよさそう。

PyCharm を雰囲気で使っているので、もっと便利な使い方を知りたい。

RedashのQuery Resultsデータソースでクエリパラメータを使用したクエリを使用する

なんとなく動いたので作業メモついでの記事。

やりたかったこと

Redash 3.0.0の大きな変更点の一つであるQuery Resultsデータソースは現時点でクエリパラメータを使用したクエリを実行できない。

ariarijp.hatenablog.com

しかし、業務で使っているRedashでは、ほとんどのクエリがクエリパラメータを必要とするため、クエリパラメータを指定してQuery Resultsデータソースを使用できるか検証してみたいと思った。

VagrantでRedashを起動

個人的に開発用途ではDockerよりVagrantのほうが何かと楽なので、Vagrantを使用する。

github.com

$ mkdir redash
$ cd redash
$ wget https://raw.githubusercontent.com/ariarijp/vagrantfiles/master/redash/Vagrantfile
$ vagrant up

VMが起動したら、 http://localhost:8080 でRedashにアクセスできる。

Query Results Exデータソースを導入

現状のQuery Results データソースはクエリパラメータに対応していないため、Query Resultsをもとにクエリパラメータ対応を入れたQuery Results Exというクエリランナーを作成した。

github.com

かなり雑なコードや、整理したら不要になるコードが含まれているので、気が向いたら書き換えるかもしれない。

これを先の手順で作成したRedash環境に導入する。

$ vagrant ssh
$ # 以下はVM内で実行
$ sudo wget -O /opt/redash/current/redash/query_runner/query_results_ex.py https://raw.githubusercontent.com/ariarijp/redash-query-runners/master/query-results-ex/query_results_ex.py
$ echo 'export REDASH_ADDITIONAL_QUERY_RUNNERS="redash.query_runner.query_results_ex"' | sudo tee -a /opt/redash/.env
$ sudo service supervisor restart

なお、このデータソースはあくまで技術的に可能かどうかの検証で作成したものなので、本番環境では使用しないことを強くおすすめする。

動作確認

adminアカウントの初期設定などは割愛。

テストデータの準備

検証でデータソースとして使用するデータソースとクエリを以下のように作成する。

データソース

パスに :memory: を指定すると、SQLiteをインメモリで実行できる。これはQuery Resultsデータソースのソースを読んで知った。

In-Memory Databases

クエリ

検証の準備を省略するため、テーブルを使用せず以下のようなクエリで動作確認する。

SELECT * FROM (
  SELECT 1 a, 'foo' b, 0.1 c
  UNION SELECT 2 a, 'bar' b, 0.2 c
  UNION SELECT 3 a, 'baz' b, 0.3 c
)
WHERE a = {{a}} AND b LIKE '%{{b}}%';

Query Results Exデータソースでクエリを実行する

データソース

  • Type: Query Results Ex (Unofficial)
  • Name: Query Results Ex

クエリ

テストデータとして作成したクエリのIDが1である場合、以下のようなクエリを実行する

SELECT * FROM query_1(a=2,b=ba);

f:id:ariarijp:20180212171558p:plain

query_[クエリID](パラメータ名1=値1,パラメータ名2=値2) のように、パラメータはカッコ内にカンマ区切りで列挙できる。

値にカンマを含むものが使用できない、文字列をシングルクォーテーションなどでくくって表記できないなどの問題はあるが、検証なのであまり気にしないでおく。

まとめ

クエリパラメータを使用したクエリでもQuery Resultsデータソースで実行できる可能性があることがわかった。

今後のアップグレードで対応されるかもしれないので、4.0.0のリリースを気にしておきたい。

Redashを2.0.0から3.0.0にアップグレードした

つい先程、社内で使っているRedashを 2.0.0.b2990 から 3.0.0.b3134 へアップグレードした。

実作業時間は15分ぐらい。作業前リハーサルは1時間ぐらいでできた気がする。

手順は公式ドキュメントのとおり。

How to Upgrade Redash · Redash Help Center

$ cd /opt/redash/current
$ sudo bin/upgrade

リハーサルはVagrantで環境を作って実施。

バックアップはディスクイメージをスナップショット取って対応。

オンプレであればPostgreSQLのダンプを取る感じになるのかなと思う。

sudo bin/upgrade を実行すると、ドキュメントにも記載がある以下のエラーが起きた。

AttributeError: 'module' object has no attribute 'SSL_ST_INIT'

これはリハーサルでも発生したものだったので、ドキュメントに従って pyOpenSSLをアップグレードして解決。

$ sudo pip install pyOpenSSL -U

pyOpenSSLをアップグレードしたら、再度 sudo bin/upgrade を実行するとアップグレードは完了。

アップグレードすると /opt/redash/redash.[新しいバージョン] ができて、 /opt/redash/current が最新バージョンのディレクトリにシンボリックリンクになるのだけれど、 settings.py をいじっている場合は旧バージョンのディレクトリ内のファイルを見ていい感じに移行する必要がある。

うちの場合は主にメモリ使用量節約のため settings.py をいじっているため対応が必要だった。

ariarijp.hatenablog.com

3.0.0 にしたモチベーションはQuery Resultsなんだけど、パラメータつきクエリを多用しているので適用が難しい。

適当にパラメータが渡せるように改造してみようかと思いつつ、Google Spreadsheetデータソースとの合わせ技でなんかできないかなとも考えているところ。

このあたりはブログネタとしてちょうどいいんだけど、Googleのサービスアカウントがどうとか説明するのが億劫になって、なかなか書く気になれない。

ariarijp.hatenablog.com

そんなことを考えるまえに、そろそろRedash Meetup #1の資料を書かないと、あっという間に2/20になってしまいそうだ。

redash-meetup.connpass.com

Redash Meetup #0.1 ハンズオン振り返り

前回のProblemを中心に簡単に振り返り。

ariarijp.hatenablog.com

前回のProblemと、それに対するアクション

  • ハンズオンの成功を第一の目標にしたため、募集人数を少なめに設定した
    • -> ちょっと増やしたものの、当日不参加も目立った
  • 募集から開催までの時間が約2週間と短めだった
    • -> 約1ヶ月前に告知できた
  • 募集を先着順にしたため、あとからイベントを知った人が参加できなかった
    • -> 増枠したので先着順のままにした
  • Advent Calendarなどで告知をしたが、すでにキャンセル待ちになっていた
    • -> ほぼ公開後に2日で埋まったので、状況それほど変わらず。当日不参加が痛い
  • ハンズオン環境構築で想定外のトラブルがいくつかあった
  • -> ハンズオンの進行方法にばらつきがあった
    • -> 今回はサポートありのもくもく会スタイルに統一した
    • -> 時間が余り気味になってしまったため、その場で小ネタを用意して発表したりもした

その他

  • Metabaseも話題になっていて、少しRedashのムーブメントが落ち着いてきた?
  • 参加者のみなさまに会場の撤収を手伝っていただけてありがたかった
  • キャンセル理由でインフルエンザの流行をより身近に感じた
  • 懇親会無しでサクッと終わるスタイルは良い。寿司ネタが消失する問題なども気にしなくて良い
  • 当日不参加はつらい、せめてキャンセルしてほしかった

まとめ

ハンズオンイベントは一区切りでいいかなと id:kakku22 と話したりしていますが、ハンズオン資料のバージョンアップや、なんらかのきっかけでまた実施するかもしれません。

ハンズオンイベントがなくても、資料に沿って進められるようになっていますので、これからRedashを使ってみようと考えているかたは是非お試しください!

github.com

次回は2/20に kyoshidajp さんと私がRedashの導入・活用事例などについてお話しする、Redash Meetup #1を開催します。

redash-meetup.connpass.com

すでにキャンセル待ちとなっていますが、ご興味があれば参加登録をお願いします。

Blazerで異常値検知を試してみる

先日の記事の続きです。

ariarijp.hatenablog.com

Blazerで異常値検知も試してみました。

検証に使用したVagrantfileは以下のものです。

github.com

vagrant up してBlazerを起動し、ブラウザでアクセスできる状態を前提にします。

サンプルを見てみる

Vagrantfileで使用している ankane/blazer-dev では、開発用のリポジトリであるためか、デフォルトで異常値検知が有効になっています。

...省略...
anomaly_checks: true
...省略...

http://localhost:3000/queries/12-check-for-anomalies にアクセスすると、以下のような画面が表示されます。

f:id:ariarijp:20180113143909p:plain

FAILING · Anomaly detected in new_ratings というメッセージが表示されており、 new_ratings の値の推移にAnomalyな値が検出されたことがわかります。

このクエリで実行されているSQLを見てみます。

http://localhost:3000/queries/12-check-for-anomalies/edit にアクセスすると、SQLの編集画面が表示され、以下のようなSQLが実行されていることがわかります。

SELECT date_trunc('week', rated_at)::date AS week, COUNT(*) AS new_ratings FROM ratings GROUP BY week ORDER BY week

SQLをいじってみる

先程は異常検知されていたので、このクエリを少し変えて、異常値が検出されないようにしてみます。

SELECT date_trunc('week', rated_at)::date AS week, COUNT(*) AS new_ratings FROM ratings GROUP BY week HAVING COUNT(*) < 5000 ORDER BY week

HAVING 句で5000件以上の行をフィルタしています。このSQLを保存し、再度クエリを実行してみると、以下のような画面が表示されます。

f:id:ariarijp:20180113144419p:plain

PASSING · No anomalies detected というメッセージが表示されており、異常値が検出されていないことがわかります。

さらにSQLを変更し、再度異常検知されるようにしてみます。

SELECT
    date_trunc('week', rated_at)::date AS week,
    CASE
        WHEN
            date_trunc('week', rated_at)::date = to_date('1998-03-09', 'YYYY-MM-DD') THEN CAST (0 AS BIGINT)
        WHEN
            date_trunc('week', rated_at)::date = to_date('1998-03-16', 'YYYY-MM-DD') THEN CAST(0 AS BIGINT)
        WHEN
            date_trunc('week', rated_at)::date = to_date('1998-03-23', 'YYYY-MM-DD') THEN CAST(0 AS BIGINT)
        ELSE COUNT(*)
    END AS new_ratings
FROM
    ratings
GROUP BY
    week HAVING COUNT(*) < 5000
ORDER BY
    week

少し長くなりましたが、もとのSQLが週単位でデータを取っているので、1998-03-09-1998-03-23週のデータを無理やり0にしてみました。 このSQLを保存し、再度クエリを実行してみると、また異常値が検知されます。

f:id:ariarijp:20180113150512p:plain

ちなみに、1週分のデータだけ0にしても異常値としては認識されませんでした。このあたりのチューニングはできるのかもしれませんが、今回はそこまで調べていません。

まとめ

データ分析などを専門にしていないエンジニアでも、Blazer(というよりRのtwitter/AnomalyDetectionパッケージ)によって異常検知が簡単に利用できました。

他のOSSのBIツールではあまり見かけた記憶がないので、異常値検知はBlazerの特徴ひとつになるかもしれません。

Rもちょっとしたパッケージを使えるぐらいには勉強しようかな。

Rではじめるデータサイエンス

Rではじめるデータサイエンス