【詳解trocco】ワークフローの「ループ機能」の使い方・活用ユースケース

## これは何？
どうも、troccoエバンジェリスト兼CPOの[@hiro_koba_jp](https://twitter.com/hiro_koba_jp)です。
この記事はtroccoの「あまり脚光を浴びていないと感じる」機能をご紹介したり、変化球的な使い方まで詳細に解説するシリーズの第1段です。
今回の記事ではtroccoのワークフローで利用できる「ループ機能」について詳解していきます。
（アドベントカレンダー初日はネタに走らず真面目に投稿します）

## ワークフロー機能とは？
まずはループ機能の前提となる「ワークフロー」機能について簡単に触れておきます。
troccoにはETL/ELTパイプラインのジョブ管理を行うための「ワークフロー」という機能があります。
ワークフロー内では以下のようなデータエンジニアに必要なオペレーションタスクがあり、作業を自動化することが出来ます。

* troccoの各種設定をトリガー
* BigQuery上のデータをチェック
* TableauやSlackとの連携
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61228/4fe4fb60-eca8-6082-cd7b-9b704c3428d0.png)

## ループ機能とは
ループ機能とは、troccoの各種ジョブをループで複数回実行することが出来る機能です。
trocco上で作成したETLジョブを、「2021/01/01 ~ 2021/12/31」の期間で繰り返し実行する、などが可能になります。
（ループのもととなるリストは様々ありますので次のセクションで紹介します）

### ループ対象となるジョブには「カスタム変数」が必要
ループ対象となる各種ジョブでは、各ループで動的に変更したいフィールドに「カスタム変数」が埋め込まれている必要があります。
カスタム変数とは、実行時にそのフィールドの「値」を動的に決定する機能です。
例えば転送元Google広告の「レポート対象日付」にカスタム変数を埋め込んでおくと、実行時に「前日の日付」を動的に展開し、最新のデータを取得することが出来るようになります。
<img width="800px" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61228/0746506c-c96f-995f-529b-caf019a79d31.png">

### ループ機能の仕組み
ループ機能は以下の仕組みによって実現されています。

1. ループのリストを定義する
1. リストを元に、ジョブを繰り返し実行する
1. 各繰り返しでは、カスタム変数に対して2の値を代入（展開）する

なお、ループの対象の変数は2つ以上指定することも可能で、かなり柔軟なループ実行が組めます。

### ループ機能の設定場所

また、ループ機能はワークフローの編集画面にて、タスクの詳細画面から以下のチェックボックスを有効化することで設定することが出来ます。
<img width="800px" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61228/5716ddcc-6e58-10cf-0c04-68898588bb3c.png">

## ループの種類と設定方法

さて、前項でご説明した「ループのリストを定義する」ですが、次の3種類の定義方法があります。

### 1. 日付範囲によるループ
この方法では、日付範囲により任意の期間を指定して繰り返し処理が出来ます。
例えば広告レポートの「レポート対象日付」をループ対象とする場合、以下のように期間を指定することで、過去データの一括取得などが出来ます。
<img width="800px" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61228/f5451bfa-83c5-529b-39e3-1bd33f369980.png">

この場合、ループの間隔は現状1日ずつのみに対応しています。
（「n時間ごと」や「1週間ごと」を指定したいケースがございましたら、[@hiro_koba_jp](https://twitter.com/hiro_koba_jp)までご要望下さい！

また展開設定の「設定期間n日前からループ」の設定では、変数ごとにオフセットを指定することが出来ます。
例えば変数が複数あって「変数ごとに期間をn日ずらしてループさせたい」みたいな用途でお使いいただけます。

「カスタム変数出力イメージ」では、ご覧の通りループの繰り返し番号と、そのループで実際に展開されるカスタム変数の値がご確認いただけます。

### 2. 値を直接指定するループ
こちら方法では、ループの元となるリストの値を直接記載し、そのリストを元に繰り返し処理を事項出来ます。
例えば広告レポートを取得する際、レポート対象のアカウントが複数ある場合などは、設定内のアカウントIDフィールドにカスタム変数を埋め込み、以下のようなループを定義することで設定を簡略化することが出来ます。
<img width="800px" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61228/2f17f260-dbc4-55f6-7558-91ac7c055051.png">

改行区切りのリストに対応しているため、スプレッドシートやExcel等で値のリストを作成し、簡単にコピー＆ペーストすることが出来るようになっています。

また、変数は複数指定することも可能ですので、かなり柔軟なループが組めます。
<img width="800px" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61228/0f652309-ecee-cab5-a3fc-2e8e852313cc.png">

### 3. BigQueryのクエリ結果を用いた動的なループ
最後の方法では、DWH（現状ではBigQueryのみに対応）に対してクエリを実行し、結果を元にループ実行を行うことができます。
この方法を利用することで、動的に変わるリストを元にループすることが出来ます。
すごいです。相当に柔軟です。例えばユーザーIDを動的にクエリで抽出して外部API等に連携したり、様々な活用が出来ます。

ループの種類から以下の「BigQueryの結果でループ」を選択して、ループ対象の変数を指定します。
<img width="800px" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61228/74ebd08f-58ba-aaae-222b-2581372dfa5c.png">

すると以下のようなクエリエディタが出現しますので、ループの元となる値を抽出するようにクエリを記述します。
今回は1つのカスタム変数でループさせるようなサンプルクエリを記述し、「プレビュー実行」を押して変数の展開がどのように行われるか確認します。
<img width="800px" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61228/0ff61975-b557-a55e-c01e-9b2a57ba6e17.png">
今回は1つの変数だったので自明ですが、ループ対象の「カスタム変数」と「クエリ内の列名」がちゃんとマッピングされているのでわかりやすいですね。
なお、BigQueryへの接続には「接続情報」としてご登録いただいている認証情報を利用することが出来ます。

## ループの制御

### エラーハンドリング
エラーハンドリング、もちろんちゃんと出来ます。
ループの設定項目にて、以下のように3種類の挙動を選ぶことが出来ます。
<img width="400px" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61228/c663486a-91c6-686f-1ca0-2cc521db75cd.png">

|エラーハンドリング|挙動|
|:-----:|:-----|
|**エラー発生時にループを停止**|ループ内でエラーが発生した場合、その時点でループを停止し、ループが組み込まれているワークフロータスク自体をエラー終了させます。|
|**すべてのエラーをスキップ**|ループ内でエラーが発生した場合も処理を継続し、最後までループを完走させようとします。完走後、ループが組み込まれているワークフロータスク自体をエラー終了させます。|
|**上限回数までエラーをスキップ**|任意の上限回数を指定し、その上限回数まではエラーをスキップしてループ処理を継続します。上限回数に達した時点でループは強制終了されます。エラーが1つでも存在した場合、ループが組み込まれているワークフロータスク自体をエラー終了させます。|

ループが組み込まれているワークフロータスクがエラーとなった場合、後続の処理を実行するかは、ワークフロー側の設定「タスクのエラーハンドリング - タスクエラー時も後続タスクを続行」によって設定が可能です。

### 並列実行
ループ処理はデフォルトで1並列で逐次実行されますが、並列実行することも出来ます。
ループの設定項目内の以下トグルをONにすることで、ループを並列処理することが出来ます。

<img width="400px" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61228/79ddc089-a069-73e8-aed8-1133409e92cd.png">

並列数はワークフロー側の設定値「タスク同時実行上限数」によって決まります。
また、ループが組み込まれているタスクの他に、並列してタスクが実行されている場合は上記並列数より低い並列数となります。
（タスク同時実行上限数が5で、ループが組み込まれているタスク以外に2つのタスクが並列実行されている場合、ループは3並列で処理されます）

なお、並列実行を有効化した場合、ループ内の実行順序は保証されない点ご留意下さい。

## 活用ユースケース
すみません、タイムオーバーなので余裕が出来たら記述します・・・多分以下を書きます。

* BigQueryクエリループを使って動的に外部APIコール！
* 確定していない過去30日の広告成果レポートを、一気に洗い替えてリアルタイム＆正確なレポーティング！


## まとめ

今回はワークフロー機能の中にある「ループ機能」について詳解しました。
単純な文字列・日付範囲でのループから、複数変数を用いた複雑なループ、BigQueryのクエリ結果に基づく動的なループまで、かなり柔軟なループ処理が実現できることが分かっていただけたかと思います。
更にループ機能とプログラミングETL機能をかけ合わせるといったあわせ技を使えば可能性は無限大ですね・・・！
今後もtroccoの「あまり脚光を浴びていない機能」や「変化球的な使い方」をご紹介していければと思います。
よかったら著者のTwitterをフォローして頂けると、記事作成時に通知を行ったり、データエンジニアの方に有益な情報をキャッチアップできるのでお願いいたします↓
[@hiro_koba_jp](https://twitter.com/hiro_koba_jp)