Python
re
redash

re:dashでpythonを使う vol.1

More than 1 year has passed since last update.

株式会社オズビジョン@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'})

image.png

ドキュメンテーションがあった

大した量もない驚愕のシンプルさ。
コードがすべてを物語っている気がしますが、量も少ないので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

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

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

    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})

image.png

(∩´∀`)∩

おわりに

とりあえずなんとかそれっぽいものできました!
次は実際のDBにクエリを投げて値を加工したいと…おもって…ます。

また次のエントリでお会いしましょう。
おしまい。


Appendix

https://redash.io/help-onpremise/how-rd-works/data-source-results-format.html

データソース結果のフォーマットについて

使えるのは以下の型

  • 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"
    }
  ]
}