re:dashのQuery Snippetsについて
re:dash Advent Calendar 2016 2日目の記事です。
Query Snippetsとは
0.12で追加されたre:dashの新機能で、よくあるSQLを文字通りスニペットとして登録することができ、クエリエディター上でSQLを書く際に、特定のキーワードに反応してスニペットを保管してくれます。
今年のre:dash Advent Calendar 1日目の記事でも少し触れられていました。
スニペットを登録する
0.12ではSettingsにメニューが追加されていますので、試しにスニペットを登録してみます。
Triggerにはどんな文字列が入力されたときにスニペットで補完するかを指定できるので、ここでは__cnt
としています。アンダースコア2つを付けたのは、スニペットだとわかるようにするためですが、どんな文字列でもよいと思います。
Descriptionは必須ではないのですが、説明を書いておいたほうがよいでしょう。
Snippetに補完したいSQLを書きます。
ここで ${1:table}
という文字列を使用していますが、これについては後述します。
一通り書き終わったら保存しましょう。
スニペットを使用する
スニペットを登録したら、クエリエディターで使用してみます。
クエリエディター上で __
と入力すると __cnt
が補完され、決定すると __cnt
でトリガーされるスニペットがエディター上に展開されます。
先程、 ${1:table}
と入力した箇所はプレースホルダーになりますので、その箇所をテーブル名で置き換えてクエリーを実行しました。
プレースホルダーは複数記述することができ、エディター上ではTABキーで移動しながら入力できます。
テーブル名やカラム名の補完も相まって、すばやくSQLを書くことができますね。
まとめ
スニペットを使うことで作業の効率化はもとより、エンジニアでなくてもある程度お決まりのSQLが書けるようになるかもしれません。
また、似たようなクエリーを無邪気にForkしていくと、あっという間にクエリーが増えていくので、使い回しの効くものをスニペットにしておくというような運用もよさそうです。
とはいえ、実は現在プロダクションで使用しているバージョンが0.10なので、アップデートから検討しなければいけないというのが、個人的な悩み事です。
re:dash Advent Calendar 2016 について
まだまだ枠が空いているようです。
今年はre:dashが話題にあがることも多かったですし、実際に使われているかたも増えているような印象なので、小ネタでも参加してみてはいかがでしょうか?
supersetをVagrantで起動する
週末にこの記事を読んでsupersetを試してみたくなったので、Vagrantで起動できるようにしてみました。
VagrantfileでShell Provisioningしている環境構築手順は、ほぼ公式ドキュメントのインストール手順通りです。
Installation & Configuration — Superset's documentation documentation
使い方
Gistからシェルスクリプトをダウンロードして実行するだけです。
$ mkdir superset $ cd superset $ wget https://gist.githubusercontent.com/ariarijp/f04c51feff8bfff73a53e7958474a942/raw/db67ddac46e53dbd3db139c3e7abdf8a4f70f504/run.sh $ chmod +x run.sh $ ./run.sh
VMが起動したら、ブラウザで http://localhost:8088/ にアクセスすると、以下のような画面が表示されます。
ユーザー名とパスワードは admin / superset
としていますので、それらを入力してログインします。
ログインできました。あとはサンプルのダッシュボードを見たりしてみましょう。
まとめ
DockerではなくVagrantを使ってみましたが、ドキュメント通りで特に困ること無く環境構築できました。
FullPageOSでRaspberry Piをキオスク端末にする
なぜか家に2つも転がっているRaspberry PI 2を見て、ふと思い立ったのでキオスク端末にしてみました。あまり使わないけれど、Raspberry Pi 3がなんとなく欲しいです。
Raspberry Pi3 Model B ボード&ケースセット (Element14版, Clear)-Physical Computing Lab
- 出版社/メーカー: TechShare
- メディア: エレクトロニクス
- この商品を含むブログ (3件) を見る
「Raspberry Pi Kiosk」で検索すると、起動時にChromiumを自動的に実行するように設定するのが一般的なようですが、FullPageOSというそれっぽい名前のRaspbian派生OSを見つけました。
FullPageOSも起動時にChromiumをキオスクモードで起動しているだけではあるのですが、インストールするだけで目的が達成できそうなので、これを使ってみることにしました。
インストール
READMEに記載されているミラーサイトからダウンロードします。
2016/11/14現在は「2016-07-20_2016-05-27-fullpageos-jessie-lite-0.7.0.zip」が最新版のようです。
ダウンロードしたファイルをunzip
などで展開すると、2016-05-27-fullpageos-jessie-lite-0.7.0.img
ファイルができるので、このファイルをRaspbian導入時と同じようにdd
コマンドなどでSDカードに書き込みます。
起動
起動については特に他のOSと変わらず、MicroSDを挿した状態で電源ケーブルを差し込むだけです。
ディスプレイを繋いでも表示されない場合は、HDMIケーブルを挿した状態で電源ケーブルを挿し直してみてください。
起動が完了するとChromiumでWelcomeページが表示されます。
SSHでログイン
FullPageOSはBonjourを使って fullpageos.local
でアクセスできるようになっているので、このアドレスを使ってSSHログインすることができます。
デフォルトのユーザー名/パスワードはRaspbian同様に pi / raspberry
です。
無線LANの設定
無線LANの環境があれば配線も楽なので、Raspberry Piも無線で使いたい場合が多いと思います。
FullPageOSは起動時にChromiumがフルスクリーンで起動されるため、GUIで設定をすることは(おそらく)できません。
代わりに、ネットワークなどの主要な設定はテキストファイルに記述することができます。
無線LANの設定は /boot/fullpageos-network.txt
を書き換えることで設定できます。
... ## WPA/WPA2 secured iface wlan0-fullpageos inet manual wpa-ssid "アクセスポイントのSSID" wpa-psk "パスワード" ...
表示される画面の設定
FullPageOSには、いくつかの画面をローテーション表示する仕組みがデフォルトで備わっています。
仕組みと言っても、中身は登録されたURLをiframe
で表示し、一定時間で切り替えるだけの簡素なものですが、ブラウザ上でタブの追加・削除ができるようになっており、画面を表示するだけなら特に不自由もないと思います。
また、 http://fullpageos.local/FullPageDashboard でRaspberry Pi以外のブラウザからもアクセスすることができます。
以下の例はDashingのデモページを表示するようにしてみたものです。
不便なところ
外部のブラウザからFullPageDashboardで設定を書き換えたときに、画面を再読込することができないため、毎回 reboot
などで再起動することになります。
多少不便ではありますが、そんなに画面を追加・削除するものでもないですし、起動も数分で済むのでこれは気にしないようにしていますが、少し不便です。
Raspberry Piにキーボードを繋げてしまえばそれで済む話なのですが、それなら再起動してしまったほうが楽かなと思ってそうしています。
まとめ
執務室内にダッシュボード的に大型のディスプレイを置く会社も増えてきていますが、最近のディスプレイはUSB端子もあるので、USB給電が可能という点でもRaspberry Piを使用するというのもよいかもしれません。
その場合、Raspberry Pi 3は電源を選ぶので、あえてRaspberry Pi 2というのもありですね。
エンジニア立ち居振舞い: なぜ必要なのかをちゃんと聞く
なぜ必要なのかをちゃんと聞く
今の主な仕事は社外向けと社内向けのものがあって、今回は後者の話。
いわゆる「社内ツール」というようなやつで、定形作業の負荷を少しでも減らすとか、誰かの職人芸でなんとかやってる作業を、うまく仕組みにして誰でもできるようにするとか、あとはデータを上手く集めて、ちょっと扱いやすく加工したりとか、そういうこともやっている。
で、社内でそういった困り事を相談してくれる人たちは、当然ながら自分よりも彼らの業務をよく知っていて、そのうえで「こんなことをしたい」という相談をしてくれるし、自分もある程度はその業務がどのように改善されるかとか、どんな設計にしたらいいか、どんなデータを集めてあげればいいかは想像がすることができる程度の業務知識はあるけど、そういった話のなかですっぽりと抜け落ちることがあるのが「なんでそれが必要なのか」じゃないかと思う。
自分はせっかちなので、「なるほど。そういうことね」とか、「あ、これでいける」と思ったらすぐに手を動かしてしまいたくなる。そういうときこそ、ちょっと意識的に「なんでそれがあると嬉しいんだろう?なんで必要なんだろう?」というのを、ここ数年は考えたり、直接聞いてみたりするようになった。
「なぜ必要なのか?」と改めて聞いてみると、自分のイメージ通りだったりもするし、ズレてた認識を修正できるかもしれないし、それはすでに別のツールがカバーしている問題かもしれないし、もしかしたら、もっと別の大きな課題が今の状況を引き起こしていることに気づくかもしれない。特に最後に挙げたようなものが見つかれば儲けものだ。
「ユーザーは自分が何を求めているか、ユーザー自身はそれを本当に知っているのか?」というのを、この前プロダクトマネージャーカンファレンスでも聞いた気がする。ちょっとした社内ツールでも、「なんでそれが必要なのか?」を(社内の)ユーザーから引き出し、エンジニアとして彼らの困り事を本当に解決するものを作っていきたいなと思っている。
re:dashでよく使われているクエリーを調べる
re:dashのFork機能はすごく好きなんだけど、便利すぎて気軽にForkされる結果、使ってるのか使ってないのかわからないクエリーが増えてしまいがち。
この記事をみたら統計情報っぽいのが取れるようなので、ちょっといじって以下のようにした。
使用しているバージョンは 0.10.1+b1836
。
SELECT object_id AS query_id, SUM(CASE WHEN action = 'view' THEN 1 ELSE 0 END) AS view, SUM(CASE WHEN action = 'execute' THEN 1 ELSE 0 END) AS execute FROM events WHERE object_type = 'query' AND object_id != '' AND created_at BETWEEN to_date('2016-11-01', 'YYYY-MM-DD') AND to_date('2016-11-17', 'YYYY-MM-DD') GROUP BY object_id ORDER BY execute DESC;
結果はこんな感じ。
object_id | view | execute -----------+------+--------- 78 | 125 | 99 68 | 123 | 106 87 | 68 | 66 79 | 68 | 55 85 | 68 | 42 103 | 63 | 50 107 | 59 | 43 8 | 58 | 13 89 | 53 | 7 125 | 52 | 28 109 | 48 | 21 104 | 44 | 11 112 | 39 | 21 100 | 39 | 19 115 | 31 | 2 122 | 25 | 9
この結果をみて、使用頻度の低いクエリーは積極的にアーカイブすることができそう。
おまけ
events
テーブルはこんな感じ。
テーブル "public.events" 列 | 型 | 修飾語 -----------------------+--------------------------+----------------------------------------------------- id | integer | not null default nextval('events_id_seq'::regclass) org_id | integer | not null user_id | integer | action | character varying(255) | not null object_type | character varying(255) | not null object_id | character varying(255) | additional_properties | text | created_at | timestamp with time zone | not null インデックス: "events_pkey" PRIMARY KEY, btree (id) "events_org_id" btree (org_id) "events_user_id" btree (user_id) 外部キー制約: "events_org_id_fkey" FOREIGN KEY (org_id) REFERENCES organizations(id) "events_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
action
, object_type
にはこんな値が入っていた。
action
add_data_source add_member api_get archive autorefresh cancel_execute change_data_source_permission create delete edit edit_description edit_name execute execute_query fork login pivot remove_data_source remove_member search update update_data_source view view_source
object_type
dashboard data_source datasource group group_data_sources page query redash user visualization widget