TROCCO®ワークフローのカスタム変数とループ実行を完全に理解する


# 概要
TROCCO®の機能のなかでユニークなものであるカスタム変数について取り扱います。
カスタム変数は便利な機能ではありますが、初心者の方には少し複雑に見えるかもしれません。ここでは展開される値の優先度やされ方について特に焦点を当てたものとしたいと思います。
また、ワークフローにおけるカスタム変数ループについても同様に紹介したいと思います。


この記事を読むことでわかるようになること
- TROCCO®ワークフローにおけるカスタム変数、およびループ実行の変数の優先度や展開のされ方について理解できる
- カスタム変数のループ実行がわかるということは複雑なパイプラインがよりかんたんに構築できるかも


# TROCCO®のワークフローとは
https://trocco.io/lp/function/workflow.html

データのフローとして例えば Google AdsからS3にデータを蓄積させ、S3からDWH、最後にBIツールで可視化するために中間テーブルを作成する、といった一連のパイプラインを簡単に構築できるような機能となります。
他にもDWHのデータのレコード数に応じて失敗としてハンドリングするデータチェック機能や任意のHTTPリクエストをパイプラインに入れることができたりします。

HTTPリクエストについては下記記事が参考になりそうです。
https://qiita.com/hgkcho/items/27ef005401ff91f7154d


# カスタム変数とは
https://documents.trocco.io/docs/custom-variables

転送設定やデータマート定義、ワークフローのタスクにもカスタム変数という可変な値を入れることができる機能があります。キューイングされた日時や実行時間などを記録するための用途や転送設定やデータマートの定義時に定めることができない値を変数として定義しておき実行時にバインドすることができます。このあたり詳しく後述します。

# カスタム変数ループとは

https://documents.trocco.io/docs/loop-using-custom-variables

その名の通り、カスタム変数をループして実行する機能です。今回深堀りたい機能となります。
日時を範囲指定して1日ごとに転送設定をループで実行したりBigqueryやsnowflakeに実際にselectした結果を元にループ実行といった高度なことまで対応しています。


# 準備


## まずはカスタム変数が定義されている転送設定を用意しよう

カスタム変数ループをするものが必要なので、カスタム変数の定義された転送設定を用意します。
ここでは転送元snowflakeから転送先snowflakeに転送する設定で以下のカスタム変数を用意しました。

![スクリーンショット 2024-07-31 20.28.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/c9d4ce10-55c5-20d3-e61f-23909ee32417.png)


- `$var_string$`
  - データ型を文字列としてデフォルトの値を `default_string`としてます
- `$var_queued_date$`
  - 時刻・日付（キューイング時）としました
-  `$var_execution_date$`
  - 時刻・日付（実行時）としました


転送先のテーブル名に以下のようにカスタム変数を元に名前が決定するようにして検証がわかりやすくします。

![スクリーンショット 2024-07-31 20.46.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/5f245ab6-7bb5-a4db-302e-b81ccedab6da.png)


## 転送設定を単体で動かしたときにどうなるかを確かめる

↑で作成した転送を手動で一度実行してみます。カスタム変数の展開方法は現在時刻を基準に展開をします。これはスケジュール実行の場合もこの設定で実行されます。余談ですが、現在時刻以外にも指定した時刻での実行と変数ごとに指定の値を入れて実行ができます。いずれも名前の通り、指定した時間がそのままカスタム変数に入ったり、文字列の場合はその文字列がカスタム変数に展開されます。

![スクリーンショット 2024-07-31 20.57.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/3fb07725-ec70-e630-8af4-d8fafdc1f00c.png)


実行した結果が以下です


![スクリーンショット 2024-07-31 21.00.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/0f487478-7961-546b-9de0-abfc2c2a1420.png)

実際にできたテーブル名

`<DATABASE>.<SCHEMA>."qiita_test_default_string_2024-07-31 20:59:32_2024-07-31 20:59:44"`


ここでわかったこと
- 文字列としてのカスタム変数は現在時刻で実行するとデフォルトの値で展開される
- キューイング時の時刻での展開は　`カスタム変数展開時刻`と一致した時間で展開された
- 実行時の時刻での展開は `実行開始日時`一致した時間で展開された

キューイング時の時刻は「実行ボタン」を押した時間に一致した時間で、実行時の時刻は実際にTROCCO®で処理を開始した時間が展開されています。


これで準備と事前知識は理解しました。早速次からワークフローでカスタム変数のループ実行をしてみましょう。



# ワークフローでループ実行を定義してみよう

![スクリーンショット 2024-07-31 21.13.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/60fc6ea6-b8fd-fa9d-4978-ed1ba0aa3609.png)

ループ実行にはいくつか種類がありますが、シンプルな期間でのループでカスタム変数の展開のされ方を見ていきます。以下ように定義してみました。違いがわかるように `$var_execution_date$`のほうを現在から1年前 `$var_queud_date$`から2年前に設定します。

![スクリーンショット 2024-07-31 21.32.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/d197f3af-fbca-aafd-ac04-82bd0d69da54.png)


これでワークフローを保存すればループ実行を含むワークフローの完成です。早速実行してどう展開されるのか見ていきましょう。

## ワークフロー実行を「現在時刻を基準に展開」で展開してみる

![スクリーンショット 2024-07-31 21.18.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/b68252cd-9c0d-8b71-03f3-2477ddac31ef.png)

↑で作成したループ実行を含むワークフローを「現在時刻を基準に展開」で展開してみます。転送設定を単体で実行したときとの差があるのか見ていきます。実際に実行した結果が以下です。

![スクリーンショット 2024-07-31 21.44.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/ef690b7c-03d1-0c44-2894-467568f72448.png)



ここからわかること
- キューイング時の時刻での展開としたカスタム変数は**ループ実行側で指定した値を現在時刻を元に展開**された
- 実行時の時刻での展開としたカスタム変数も同じく**ループ実行側で指定した値を現在時刻を元に展開**された

-> 転送設定単体で実行したときはキューイング時と実行時で展開される日時は違いましたが、ループ実行の場合はワークフローのループ実行側の設定が優先されることがわかった


## ワークフロー実行を「指定時刻を基準に展開」で展開してみる
現在時刻を基準に展開について挙動がわかったので、つぎに「指定日時を基準に展開」での実行を検証してみます。

![スクリーンショット 2024-07-31 21.48.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/d9e67081-c76d-a86e-6f96-fd21f0a27b6f.png)

ここではわかりやすく2000年の日付を指定して実行します。実行結果は以下です


![スクリーンショット 2024-07-31 21.53.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/7de1731e-28f4-922c-03f4-b45d66dcaec4.png)

ここからわかること
- キューイング時の時刻での展開としたカスタム変数は**ループ実行側で指定した値を現在時刻を元に展開**された
- 実行時の時刻での展開としたカスタム変数も同じく**ループ実行側で指定した値を現在時刻を元に展開**された

-> 転送設定単体で実行する場合指定した日時が `$var_queued_date$`　には指定した日時が、`$var_exection_date$`には実際に実行を開始した日時が入りますが、ループ実行の場合はループ定義のほうが優先されます。

## ループ実行のまとめ
まとめると以下です（自明ですが・・。）

| ワークフローの実行 | 転送ジョブのカスタム変数 | ループの結果 |
| --- | --- | --- |
| 現在時刻を基準に展開 | 時刻・日付（キューイング） | ループ実行側で指定した値を現在時刻を元に展開 |
| 現在時刻を基準に展開 | 時刻・日付（実行時） | ループ実行側で指定した値を現在時刻を元に展開 |
| 指定日時を基準に展開 | 時刻・日付（キューイング） | ループ実行側で指定した値を現在時刻を元に展開 |
| 指定日時を基準に展開 | 時刻・日付（実行時） | ループ実行側で指定した値を現在時刻を元に展開 |

比較のため、転送設定を単体またはループ実行でない状態でワークフロー実行した場合も記載しておきます。

| 実行パラメータ | 転送ジョブのカスタム変数 | 結果 |
| --- | --- | --- |
| 現在時刻を基準に展開 | 時刻・日付（キューイング） | 「実行ボタン」を押したタイミング(スケジュール実行が開始された時刻) |
| 現在時刻を基準に展開 | 時刻・日付（実行時） | 実際に処理を始めた時刻 |
| 指定日時を基準に展開 | 時刻・日付（キューイング） | 指定した時刻 |
| 指定日時を基準に展開 | 時刻・日付（実行時） | **実際に処理を始めた時刻** |

ループ実行の場合、手動実行時に上書きをした時刻は適用されず、あくまでループ実行で定めた値が優先されます。もしワークフローで定義したカスタム変数とループ実行で定義したカスタム変数が重複している場合（紛らわしいのでそのようなワークフロー定義をそもそも作成しないとしたほうが良さそう）はこのような変数の展開順序について注意をしたうえで設定することをおすすめします。


# 他に細かい挙動をいくつか見てみる

ここまでで基本的な挙動については理解できたと思います。ここからはエッジケースにいくつか焦点を当ててどういう挙動となるのかを見ていきたいと思います。

## 転送設定のカスタムにカスタム変数が複数あり、一部を上書きしないときの挙動

先ほど取り上げた転送設定には `$var_string$` `$var_queued_date$` `$var_execution_date$`の3つがありました。
カスタム変数の展開方法として「変数ごとに値を指定」という項目があり、その名の通り展開値を指定した文字列で展開するという機能になります。

手動実行画面で以下のように展開してみます。 `$var_execution_date$` については指定せず実行してみます。

![スクリーンショット 2024-08-16 22.24.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/001a9c32-3dae-d6c5-c2c4-393d7a862d84.png)


展開値は以下となりました。

![スクリーンショット 2024-08-16 22.28.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/e26884fd-2c74-e0df-0246-f2bcf3e002a6.png)

実際に実行した日時ではなく**空文字**で展開されました。指定しなかった値は転送設定で指定した「実行時間」が展開されるのではなく空文字で上書きしたと解釈するのが良さそうです。


## カスタム変数ループで一部の変数のみループで変数を定義した時にそれ以外の変数はどうなるのか

先ほど作成した転送設定で定義されている  `$var_string$` `$var_queued_date$` `$var_execution_date$` のうち `$var_execution_date$` それぞれどれかを指定しないカスタム変数ループをそれぞれ実行してみて指定しなかった場合どのような値で実行されるのかを見ていきます。

### `$var_string$`を指定しないループ実行

![スクリーンショット 2024-08-16 22.45.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/9c5d7eef-2d8f-ce3b-e73b-60cdae150527.png)

こんなループ実行の定義にしてワークフローを実行してみます。結果は以下です

![スクリーンショット 2024-08-16 22.47.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/c9a4b553-08ff-e4ed-06ec-f2a876cf0fd2.png)

![スクリーンショット 2024-08-16 22.47.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/b2a7678c-46ff-b660-3944-d00f48d646e1.png)


ここからわかることとしては、転送設定側で「文字列として展開」としたカスタム変数をループ実行で指定せずに実行すると転送設定側で指定した文字列で展開されるということです。

### `$var_queued_date$`を指定しないループ実行

↑の結果を踏まえると転送設定で指定したようにキューイング時の時間で展開されるのかなという期待はありますが、以下の設定で実行してみます。

![スクリーンショット 2024-08-16 22.52.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/f9d7f7c6-96d7-be47-1ff5-32e9a55ca947.png)

↓は結果

![スクリーンショット 2024-08-16 22.54.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/ab5d52f2-d47f-5615-9ef8-33a4a4c3063e.png)

期待通り指定しなかった `$var_queued_date$` はキューイング時の時刻で展開されました。


### `$var_execution_date$`を指定しないループ実行

ここまで来ると結果は自明ですが、`$var_execution_date$`　をループ実行側で指定しなかった場合どのような値が展開されるのかも念の為見ておきます。おそらく実際の実行時間で展開されます


![スクリーンショット 2024-08-16 22.57.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/d0f4b37d-d703-38c6-69c3-411ade28c5fe.png)



![スクリーンショット 2024-08-16 22.58.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155328/10d5cbb0-5b6f-5f81-165e-d33128f8c260.png)

期待通り実際の実行時間で展開されましたね。

### まとめ
カスタム変数ループで一部の変数のみループで変数を定義した時にそれ以外の変数はどうなるのか、というと**転送設定側で指定したデフォルトの展開値**が展開される、ということになります。


# おわりに
記事の前半ではカスタム変数とループ実行の基本的な挙動について確認しました。後半ではいくつかエッジケースを取り上げその時どのような挙動になるのかをいくつか見てみました。少しはカスタム変数について解像度が上がったのであれば嬉しいです。

そもそもTROCCO触ったことないんだよな、という方はフリープラン（無料です）を提供しているのでこの機会に申し込んでみて、色々データの転送をしてみると良いと思います。その際には上記で取り上げたカスタム変数も使ってみてくれると嬉しいです。

https://trocco.io/lp/inquiry_free.html