do-while ノードは、プログラミングにおける do-while 制御フロー パターンを DataWorks が実装したものです。このノードは、[終了] ノードが False を返すまで、内部ワークフローを繰り返し実行します。do-while ノードを使用して、ループを実行したり、代入ノードの結果セットを反復処理したり、スケジューリング ワークフローで条件付きリトライ ロジックを実装したりできます。
仕組み
do-while ノードが実行されると、その内部ワークフローを逐次的なループで実行します — 並列実行はサポートされていないため、次のループを開始する前に各ループが完了する必要があります。各ループの終了時に、[end] ノードが条件を評価し、True(ループを継続)または False(終了)のいずれかを返します。ループの上限は 1,024 回の反復です。この制限に達した場合、end ノードは自動的に False を返します。
内部ワークフローは常に開始ノードで開始し、[終了] ノードで終了します。その間には、ワークフローで必要なタスクノードを配置できます。DataWorks は組み込み変数を提供しているため、タスクノードと終了ノードは、ループ状態 (現在のループ回数、オフセット) および上位の代入ノードから渡されたデータを読み取ることができます。
制限事項
| 制限事項 | 詳細 |
|---|---|
| エディション | Standard Edition 以上。詳細については、「DataWorks エディション間の違い」をご参照ください。 |
| 最大ループ数 | 1,024。これを超えると、end ノードは自動的に False を返します。 |
| 並列実行 | サポートされていません。次のループが開始する前に、各ループを完了する必要があります。 |
| テスト | 標準モードワークスペースでは、DataStudio で do-while ノードを直接テストすることはできません。ワークフローを開発環境のオペレーションセンターにコミットしてデプロイし、そこからタスクを実行してください。 |
| end ノードコード | end ノードコードではコメントはサポートされていません。 |
ノード構成
do-while ノードを作成すると、DataWorks は自動的に 3 つの内部ノードを作成します。
| ノード | 役割 | 削除可能ですか? |
|---|---|---|
| [start] | 各ループの開始を示します。タスクノードはこれに依存し、それ自体は処理を行いません。 | いいえ |
| [shell] (デフォルトタスクノード) | プレースホルダーのシェルタスクノードです。これを削除し、ワークフローに必要なタスクノードに置き換えてください。 | はい |
| end | 終了条件を評価し、True または False を返します。本質的には代入ノードであり、すべてのタスクノードの子孫である必要があります。 | いいえ |
内部ワークフローは常に start で開始し、[end] で終了する必要があります。内部ノード間の依存関係を削除および再設定して、その間に任意のワークフロー構造を構築できます。
内部ワークフローで条件付きロジックまたは結果の走査にブランチノードを使用する場合、マージノードも必要です。詳細については、「マージノードの設定」をご参照ください。

組み込み変数
do-while ノードは、${dag.<variable>} 形式の組み込み変数を提供します。これらをタスクノードコードと end ノードコードで使用して、ループ状態または祖先の代入ノードからのデータを読み取ることができます。
ループ状態変数
これらの変数は、代入ノードを使用するかどうかにかかわらず、常に利用可能です。
| 変数 | 説明 | ループ 1 | ループ 2 | ループ n |
|---|---|---|---|---|
${dag.loopTimes} | 完了したループ回数 | 1 | 2 | n |
${dag.offset} | 現在のループのゼロベースインデックス | 0 | 1 | n-1 |
代入ノード変数
do-while ノードが 代入ノード に依存する場合、代入ノードの出力パラメーターを do-while ノードの [入力パラメーター] に渡すことができます。入力パラメーターは ${dag.<parameter-name>} フォーマットに従います。ここで <parameter-name> は、do-while ノードの [入力パラメーター] で設定した名前と一致します。
以下の表では、input は設定する実際のパラメーター名のプレースホルダーです。
| 変数 | 説明 |
|---|---|
${dag.input} | 祖先の代入ノードによって渡された完全なデータセット |
${dag.input[${dag.offset}]} | 現在のループのデータ入力 |
${dag.input.length} | データセット内のエントリ数 |
代入ノードの出力パラメーターを、代入ノードの 出力パラメーター に追加し、次にそれらを do-while ノードの内側のシェルノード(do-while ノード自体ではなく)の [入力パラメーター] に追加します。内側のシェルノードは、コード内でこれらの変数を使用してデータを読み取ります。
代入ノードの種類ごとの変数の値
データ形式は、代入ノードで使用される言語によって異なります。
| 割り当てノードタイプ | データフォーマット | ${dag.input[${dag.offset}]} |
|---|---|---|
| Shell | 1次元配列 (カンマ区切り値) | 2021-03-28 (ループ 1)、2021-03-29 (ループ 2) |
| ODPS SQL | 2次元配列 (行と列) | 0016359810821, Hubei Province, 30 to 40 years old, Cancer (ループ 1) |
出力形式の詳細については、「出力パラメーターの出力形式」をご参照ください。
例 1: シェル代入ノード
代入ノードは以下を出力します: 2021-03-28,2021-03-29,2021-03-30,2021-03-31,2021-04-01
| 変数 | ループ 1 | ループ 2 |
|---|---|---|
${dag.input} | 2021-03-28,2021-03-29,2021-03-30,2021-03-31,2021-04-01 | (同じ) |
${dag.input[${dag.offset}]} | 2021-03-28 | 2021-03-29 |
${dag.input.length} | 5 | (同じ) |
${dag.loopTimes} | 1 | 2 |
${dag.offset} | 0 | 1 |
例 2: ODPS SQL 代入ノード
代入ノードの最後の SELECT は以下を返します。
+----------------------------------------------+
| uid | region | age_range | zodiac |
+----------------------------------------------+
| 0016359810821 | Hubei Province | 30 to 40 years old | Cancer |
| 0016359814159 | Unknown | 30 to 40 years old | Cancer |
+----------------------------------------------+| 変数 | ループ 1 | ループ 2 |
|---|---|---|
${dag.input} | 上記の完全なテーブル | (同様) |
${dag.input[${dag.offset}]} | 0016359810821, 湖北省, 30 歳~40 歳, 癌 | 0016359814159, 不明, 30 歳~40 歳, 癌 |
${dag.input.length} | 2(行数) | (同様) |
${dag.input[0][1]} | 湖北省(0 行目、1 列目) | — |
${dag.loopTimes} | 1 | 2 |
${dag.offset} | 0 | 1 |
終了ノードのコード
終了ノードは、ループを続行するには True を、終了するには False を返す必要があります。終了ノードのコードは、ODPS SQL、シェル、または Python 2 で記述します。終了ノードのコードではコメントはサポートされていません。
ODPS SQL
10 回ループした後、またはテーブルが空の場合に終了します:
SELECT CASE
WHEN COUNT(1) > 0 AND ${dag.offset} <= 9
THEN true
ELSE false
END
FROM xc_dpe_e2.xc_rpt_user_info_d
WHERE dt = '20200101';このクエリは、行数と現在のオフセットを固定値と比較します。${dag.offset} が 9 を超える (10 回のループ後)、またはテーブルが行を返さない場合、終了ノードは false を返します。
シェル
5 回ループした後に終了します:
if [ ${dag.loopTimes} -lt 5 ]; then
echo "True"
else
echo "False"
fi${dag.loopTimes} は、最初のループでは 1 であり、反復ごとに 1 ずつ増分します。5 回目のループが終了すると、${dag.loopTimes} は 5 になり、条件が満たされなくなるため、終了ノードは False を出力します。
Python 2
代入ノードの結果セット内のすべての行が処理されたときに終了します:
if ${dag.loopTimes} < ${dag.input.length}:
print True
else:
print False${dag.input.length} は、データセット内のエントリ数です。ループは ${dag.loopTimes} がデータセットの長さに達するまで続行され、その時点ですべてのエントリが処理済みになります。
ユースケース
代入ノードを用いた結果セットの反復処理
代入ノードを使用してデータセットをクエリまたは計算し、その後、do-while ノードを用いてループ内で各エントリを処理します。
セットアップ:
データセットを出力する代入ノード(例:
assign_node)を作成します。assign_nodeに依存する do-while ノードを作成します。依存関係は、do-while ノード自体に対して設定する必要があります。内側のシェルノードに対しては設定しないでください。
assign_nodeの出力パラメーターを、assign_nodeの **[出力パラメーター]** に追加します。同様のパラメーターを、do-while ノード内のタスクノード(シェルノード)の **[入力パラメーター]** にも追加します。
入力パラメーターは、do-while ノードではなく、内側のシェルノード上で設定してください。
終了ノードのコード内で、すべてのエントリが処理された時点でループを終了するために、
${dag.loopTimes}および${dag.input.length}を使用します。
assign_node が出力を正しく渡していることを確認するには、オペレーションセンターのデータバックフィル機能を用いて、両方のノードを同時にデータバックフィルしてください。do-while ノード単体で実行すると、代入ノードの出力はスキップされます。

ブランチノードおよびマージノードとの連携
内側のワークフローで条件付きロジックや結果の走査が必要な場合、do-while ノード内にブランチノードおよびマージノードを追加します。
設定手順:
do-while ノード内において、ブランチノード(
branch_node)とマージノード(merge_node)を内側のワークフローの一部として接続します。ブランチノードおよびマージノードは、do-while ノード内では常にペアで使用する必要があります。
ログの表示
オペレーションセンターで do-while ノードの実行ログを表示するには、次の操作を行います。
do-while ノードを見つけ、その有向非循環グラフ (DAG) を開きます。
ノード名を右クリックし、[内部ノードの表示] を選択します。