はじめに
この記事は 株式会社Diverse Advent Calendar2021 23日目の記事です。
redash(OSS版)からSlackへKPIを通知していたところ、get_query_result()だとキャッシュしか送れないことに気づき、都度SQL実行する形に置き換えました。
※get_query_result()が用意されているものの、実行時にクエリが発行されるわけではなく、最後に実行したキャッシュを参照するだけなので今回は使わない。
Prameterを使っている場合も実行結果がキャッシュされないためこの記事のやり方が有効。
データソース(MySQL)とデータソース(Python)の2つで分けてたものをデータソース(Python)の1つに集約できます。
何ができるようになるか
- RedashのPythonでSQL実行(リアルタイム)&Slack投稿
さっそく作ってみる
SQL書く、実行する
# SQL書く
# 最新のユーザー10件を取得する
query='\
SELECT id,regist_date \
FROM user \
ORDER BY id DESC \
LIMIT 10'
# SQL実行
values = execute_query('mysql', query)['rows']
print values # 雑にredash上で確認する際に使用
# redash画面上の出力内容の設定
# Slackに通知するだけならこの部分は書かなくてOK
result = {}
add_result_column(result, 'id', 'id', 'integer')
add_result_column(result, 'regist_date', 'regist_date', 'date')
add_result_row(result, values[0])
- DBから取得したデータ(UTF-8)の取り扱い時に以下のようなエラーが出る場合はエンコードを指定する。
Error running query: <type 'exceptions.UnicodeEncodeError'> 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)
import sys
from imp import reload
reload(sys)
sys.setdefaultencoding('utf-8')
Slackに通知する
- Pythonで通知するならslack-sdk使いたいところ。だけどredashへのrequestsで頑張る。
- ※ここはググればサンプルコードいっぱいあります。
# Slackに投稿する関数の定義
def slack(content):
import requests
import json
# Incoming Webhooksで取得したURLを設定
SLACK_URL = "https://hooks.slack.com/services/hogehogehoge"
payload = {
"text": content,
}
data = json.dumps(payload)
response = requests.post(SLACK_URL, data)
# 実際に投稿する
slack('test')
SQLで取得したデータをSlackに投稿する
import sys
from imp import reload
reload(sys)
sys.setdefaultencoding('utf-8')
##############################################
def slack(content):
import requests
import json
SLACK_URL = "https://hooks.slack.com/services/hogehoge"
payload = {
"text": content
}
data = json.dumps(payload)
response = requests.post(SLACK_URL, data)
##############################################
query='\
SELECT id,regist_date \
FROM user \
ORDER BY id DESC \
LIMIT 10'
values = execute_query('dbの名前を書く', query)['rows']
# ここでSlack投稿内容を整形
content = ''
for row in values:
content = content + str(row['id']) + ':' + str(row['regist_date']) + '\n'
slack(content)
参考
add_result_column, add_result_rowの使い方について以下の方の記事を参考とさせていただきました。
https://qiita.com/terra_yucco/items/fc4d3b3270a168dbd18d