Dataformで個人プロジェクトのデータ整形を行ってみた
そのときにAPIでパイプラインを実行したときのメモ
REST API
ドキュメントはこちら
まだREST API自体がBetaらしく今の段階ではプロダクション導入とかは微妙かも
今回は個人活動の1つだったので使ってみる
API KEYの発行
画面から発行する
Project Settings -> API keysでAPI Keyを発行する
実行する
curlで実行できる
発行したAPI KEYを入れて次のようにするだけ、簡単
${project_id}はDataformのプロジェクトID
$ curl -H "Authorization: Bearer ${API_KEY}" -X POST -d '{"environmentName":"retake"}' https://api.dataform.co/v1/project/${project_id}/run
{
"id":"11111111111111"
}
確認する
$ curl -H "Authorization: Bearer ${API_KEY}" https://api.dataform.co/v1/project/${project_id}/run/${run_id}
{
"id": "11111111111111",
"status": "SUCCESSFUL",
"runLogUrl": "https://app.dataform.co/#/${project_id}/run/11111111111111"
}
project_idとCREATE RUN時に取得できるrun_idを使用してパイプラインの実行結果を確認する
失敗時はFAILED、実行中の場合はRUNNINGと表示される
こちらも簡単
実行時にConfigの値を書き換える
運用していくとなると特定の設定値を書き換えて実行したいみたいなパターンが出てくる(というか出てきた)
しかし、REST APIのリクエストBodyに何か入れて上書きするというのは2021-04-30時点ではできなそう
ドキュメントを読む限り渡せるデータの数が限られているのでvarsの内容を指定することはできない
Issueにも投げてみたが対応予定はないとのこと…
環境によってConfigの値を書き換える
Dataformにはenvironmentという概念がありこのenvironmentごとに設定を変えられる
これによりstaging,productionのように参照するブランチやdataset、schemaを変更し実行環境を分離することが可能(詳細はドキュメントを参照)
configOverride以下でdataform.jsonの設定値を上書きできる
- dataform.json
{ "warehouse": "bigquery", "defaultSchema": "dataform", "assertionSchema": "dataform_assertions", "defaultDatabase": "gcp-project-111111", "vars": { "targetMonth": "thisMonth" } }
- environments.json
{ "environments": [ { "name": "production", "gitRef": "master" }, { "name": "retake", "configOverride": { "vars": { "targetMonth": "2021-03-01" } }, "gitRef": "master" } ] }
上記はvars.targetMonthの値を上書きするretakeという環境を設定している状態
設定ファイルに固定値を入れて実行すれば環境ごとに特定変数を書き換えることは可能
再実行などで動的に変数の値を変えたいパターン
今回はパイプラインの再実行などでtargetMonthの値を変えたいというパターン
想定としては次のように何度か値を変えて実行する可能性がある
- 1回目:'2020-03-01'
- 2回目:'2020-04-01'
手動でやるなら
environments.jsonを修正してpush- curlでAPI経由の実行を数回繰り返す
environmentsで変数の値を定義するパターンだと再実行の必要が出てきたら毎度このtargetMonthの内容を変更してpushして実行というような面倒なことをしなくてはならない
ただそれ以外に良い方法がなさそう…
CLIコマンドにはそういうオプションがありそうなのに…
ということで対応方法は上記の方法しか思い浮かばなかった
微妙なのは承知の上で再実行前にenvironments.jsonの中身を書き換えてpush+APIをたたく
再実行用のEnvironmentを用意(retake)してconfigOverride.vars.targetMonthを変更してpush+APIをたたく
こういう処理が必要なパターンはだいたいsourceのデータの更新もセットなことが多いイメージなのでそのあたりを含めて自動化はCI/CDサービスなりどこかのサーバなりで行う
通知に関して
Dataformでスケジューリングを組んだ場合はSlackへの通知がされるがAPI経由での実行は手動実行という扱いのようでenrivonment.jsonで設定をしても通知が来ない
これだと実行命令を投げっぱなしで成否がわからないので困る
CI/CDサービスの通知の方に乗っかるかーということで簡単なシェルスクリプトを書いた
- bin/execute_dataform.sh
#!/bin/bash
environment=$1
project_id=${DATAFORM_PROJECT_ID}
api_token=${DATAFORM_API_TOKEN}
retry_count=0
polling() {
run_id=$1
run_status=$(curl -H "Authorization: Bearer ${api_token}" https://api.dataform.co/v1/project/${project_id}/run/${run_id})
status=$(echo ${run_status} | jq -r '.status')
case "$status" in
"FAILED" )
echo "FAILED JOB."
exit 1
;;
"SUCCESSFUL" )
echo "SUCCESS JOB."
;;
"RUNNING" )
echo "retry wait 10 seconds..."
sleep 10
retry_count=$(($retry_count+1))
polling ${run_id}
esac
}
create_run=$(curl -X POST https://api.dataform.co/v1/project/${project_id}/run \
-H "Authorization: Bearer ${api_token}" \
-d @- <<EOS
{
"environmentName":"${environment}"
}
EOS
)
run_id=$(echo $create_run | jq -r '.id')
sleep 30
polling ${run_id}
- 実行部分
./bin/execute_dataform.sh retake
これでパイプラインの成否によって終了コードで判断可能になった
あとは実行環境で通知をさせればOK
まとめ
DataformのREST APIを用いてパイプラインの実行を行った
REST APIからのパラメータ指定に関してはissue投げてみたがサクッと閉じられてしまったので対応はされなそう…
あまりこういうパターンが想定されないのかなーと思いつつワークアラウンドでしのいでおくことにしました、個人のプロジェクトだし
いろいろスマートじゃないなーと思いつつも、DataformでSQL書いてデータ整形できる体験は結構良かったのでしばらく使いそう
Dataformはこういうかゆいところに…っていうのがまだ結構あるイメージなのでプロダクションで使えるかって言うと使える範囲が結構限定的なのかなと思ったりしている