株式会社オズビジョンの@terra_yuccoです。
現在社内のBIツールとしてre:dashを導入しておりますが、この子がただクエリ書く以外に、pythonもデータソースとして使えるらしい。
ということでC:6年/PHP:3年な初心者Pythonista、社内依頼の対応のためにPythonの道に足を踏み入れました。
あ、うちのre:dashは今のところ「2.0.0+b2990」です。びっみょーに古いです。
vol.1 初日のチャレンジ
そもそもpythonの文法わかんね
ググります。解決。
いや色々流儀が違って困ってますけどね!なんとなくrubyっぽい
pythonで出力結果を作るにはどうしたらいいの
社内サンプルを参考にしてとりあえず足してみた
一応値はとれたものの、なぜこうなっているかがわからない。
column
を変えればカラム名が、value
を変えれば対象値が変化するのはわかった。それだけ。
result = {}
add_result_column(result, 'column', '', 'string')
add_result_row(result, {'column' : 'value'})
ドキュメンテーションがあった
大した量もない驚愕のシンプルさ。
コードがすべてを物語っている気がしますが、量も少ないのでAppendixに翻訳を付けました。
https://redash.io/help-onpremise/how-rd-works/data-source-results-format.html
ドキュメンテーションを読んだあとで
https://github.com/getredash/redash/blob/master/redash/query_runner/python.py
以下のメソッドたちがpythonではヘルパーメソッドとして使えそうですが、ドキュメンテーションが一切ないので、実装を読まないといけなさそう。
- execute_query
- add_result_column
- add_result_row
execute_query
- https://github.com/getredash/redash/blob/v2.0.0/redash/query_runner/python.py#L156-L177
- 機能サマリ
- すごく簡単に言えば、指定したデータソースに接続し、クエリを発行するだけ
- データソースが無かったりしたらエラーになる
- データソースは名前でもIDでも設定可能
def execute_query(data_source_name_or_id, query):
"""Run query from specific data source.
Parameters:
:data_source_name_or_id string|integer: Name or ID of the data source
:query string: Query to run
"""
add_result_column
- https://github.com/getredash/redash/blob/v2.0.0/redash/query_runner/python.py#L121-L140
- 機能サマリ
- カラムの型指定がサポートされているものかチェック
- result["columns"][]にname, friendly_name, column_typeを設定する
def add_result_column(result, column_name, friendly_name, column_type):
"""Helper function to add columns inside a Python script running in Redash in an easier way
Parameters:
:result dict: The result dict
:column_name string: Name of the column, which should be consisted of lowercase latin letters or underscore.
:friendly_name string: Name of the column for display
:column_type string: Type of the column. Check supported data types for details.
"""
add_result_row
- https://github.com/getredash/redash/blob/v2.0.0/redash/query_runner/python.py#L143-L153
- 機能サマリ
- result["rows"][]にvaluesをそのまま突っ込む
- columnsの定義に合っていないと結果が出ない
def add_result_row(result, values):
"""Helper function to add one row to results set.
Parameters:
:result dict: The result dict
:values dict: One row of result in dict. The key should be one of the column names. The value is the value of the column in this row.
"""
それっぽい結果を作り出すコードをre:dashに書いてみた
result = {}
add_result_column(result, 'id', 'id', 'integer')
add_result_column(result, 'name', 'name', 'string')
add_result_column(result, 'gender', 'gender', 'string')
add_result_column(result, 'age', 'age', 'integer')
add_result_row(result, {'id':10, 'name':'Yoshida', 'gender':'male', 'age':25})
add_result_row(result, {'id':11, 'name':'Tanaka', 'gender':'female', 'age':22})
(∩´∀`)∩
おわりに
とりあえずなんとかそれっぽいものできました!
次は実際のDBにクエリを投げて値を加工したいと…おもって…ます。
また次のエントリでお会いしましょう。
おしまい。
Appendix
データソース結果のフォーマットについて
使えるのは以下の型
- integer
- float
- boolean
- string
- datetime
- date
re:dash内の全てのデータソースは以下に示す結果をJSON形式で返します。
{
"columns" : [
{
// 必須: 結果内で重複しないカラム名を付ける
"name" : "COLUMN_NAME",
// 必須: カラムのフレンドリ名。現在は未使用なのでnameと一緒で大丈夫
"friendly_name" : "FRIENDLY_NAME",
// サポートされてる型はinteger, float, boolean, string (デフォルト), datetime (ISO-8601形式)
// 型が不明ならstringを使うこと
"type" : "VALUE_TYPE"
},
...
],
"rows" : [
{
// nameにはカラム定義に含まれているnameを使う
// VALUEはJSONとして有効な値を使う。日付型はISO-8601形式の文字列で。
"name" : VALUE,
"name2" : VALUE2
},
...
]
}
例:
{
"columns": [
{
"name": "date",
"type": "date",
"friendly_name": "date"
},
{
"name": "day_number",
"type": "integer",
"friendly_name": "day_number"
},
{
"name": "value",
"type": "integer",
"friendly_name": "value"
},
{
"name": "total",
"type": "integer",
"friendly_name": "total"
}
],
"rows": [
{
"value": 40832,
"total": 53141,
"day_number": 0,
"date": "2014-01-30"
},
{
"value": 27296,
"total": 53141,
"day_number": 1,
"date": "2014-01-30"
},
{
"value": 22982,
"total": 53141,
"day_number": 2,
"date": "2014-01-30"
}
]
}