DataWorks为您提供遍历节点(for-each节点),您可以通过for-each节点来循环遍历赋值节点传递的结果集。同时您也可以重新编排for-each节点内部的业务流程。本文为您介绍for-each节点的组成与应用逻辑。
应用场景
DataWorks的for-each节点主要用于有循环遍历的场景,且需要与赋值节点联合使用,将赋值节点作为for-each节点的上游节点,将赋值节点的输出结果赋值给for-each节点后,一次次循环来遍历赋值节点的输出结果。
使用限制与注意事项
- 上下游依赖
for-each遍历节点需要遍历赋值节点传递的值,所以赋值节点需作为for-each节点的上游节点,for-each节点需要依赖赋值节点。
- 循环支持
- 仅DataWorks标准版及以上版本支持使用for-each节点。
- for-each节点最多支持循环128次,如果超过了128次,则运行会报错。实际循环遍历次数由上游赋值节点实际输出控制。
- 一维数组类型的输出,循环遍历次数即为一维数组元素的个数。
例如,赋值节点的赋值语言为Shell或Python(Python2)时,输出结果为一维数组:
2021-03-28,2021-03-29,2021-03-30,2021-03-31,2021-04-01
,则for-each节点会循环5次完成遍历。 - 二维数组类型的输出,循环遍历次数即为二维数组元素的行数。
例如,赋值节点的赋值语言为OdpsSQL时,输出结果为二维数组:
则for-each节点会循环2次完成遍历。+----------------------------------------------+ | uid | region | age_range | zodiac | +----------------------------------------------+ | 0016359810821 | 湖北省 | 30~40岁 | 巨蟹座 | | 0016359814159 | 未知 | 30~40岁 | 巨蟹座 | +----------------------------------------------+
- 一维数组类型的输出,循环遍历次数即为一维数组元素的个数。
- 内部节点
- 您可以删除for-each节点的内部节点间的依赖关系,重新编排内部业务流程,但需要分别将start节点、end节点分别作为for-each节点内部业务流程的首末节点。
- 在for-each节点的内部节点使用分支节点进行逻辑判断或者结果遍历时,需要同时使用归并节点。
- 调测运行
- DataWorks为标准模式时,不支持在DataStudio界面直接测试运行for-each节点。
如果您想测试验证for-each节点的运行结果,您需要将包含for-each节点的任务发布提交到运维中心,在运维中心页面运行for-each节点任务。
- 在运维中心查看for-each节点的执行日志时,您需要右键实例,单击查看内部节点来查看内部节点的执行日志。
- DataWorks为标准模式时,不支持在DataStudio界面直接测试运行for-each节点。
节点组成
DataWorks的for-each节点是包含内部节点的一种特殊节点,您在创建完成for-each节点时,同时也自动创建完成了三个内部节点:start节点(循环开始节点)、sql节点(循环任务节点)、end节点(循环结束判断节点),通过内部节点组织成内部节点流程,实现对上游赋值接节点输出结果的循环遍历。
如上图所示:

- sql节点DataWorks默认为您创建好了一个SQL类型的内部任务运行节点,您也可以删除默认的sql节点后,自定义内部循环遍历任务的运行节点。
- 您的循环遍历任务是SQL类型的任务,则可以直接双击默认的sql节点,进入节点的代码开发页面开发任务代码。
- 您的循环遍历任务比较复杂,您可以在内部节点流程中新建其他任务节点,并根据实际情况重新构建节点的运行流程。
说明 自定义循环任务节点时,您可以删除内部节点间的依赖关系,重新编排循环节点内部业务流程,但需要分别将start节点、end节点分别作为for-each节点内部业务流程的首末节点。
- start节点与end节点是内部节点业务流程每次循环遍历的开始节点与结束节点,不承载具体的任务代码。说明 for-each节点的end节点不控制循环遍历的次数,for-each节点的循环遍历次数由上游赋值节点实际输出控制。
内置变量
DataWorks的for-each节点每次循环遍历赋值节点的输出结果时,您可以通过一些内置的变量来获取当前已循环次数和偏移量。
内置变量 | 含义 | 与for循环对比 |
---|---|---|
${dag.loopDataArray} |
获取赋值节点的数据集 | 相当于for循环中的代码结果:
|
${dag.foreach.current} |
获取当前遍历值 | 以下面的for循环代码为例:
|
${dag.offset} |
当前偏移量(每一次遍历相对于第一次的偏移量) | |
${dag.loopTimes} |
获取当前遍历次数 | - |
在您了解自己输出的表结构的情况下,您可以使用如下变量方式,获取其他变量取值。
其他变量 | 含义 |
---|---|
${dag.foreach.current[n]} |
上游赋值节点的输出结果为二维数组时,每次遍历时获取当前数据行的某列的数据。 |
${dag.loopDataArray[i][j]} |
上游赋值节点的输出结果为二维数组时,获取数据集中具体i行j列的数据。 |
${dag.foreach.current[n]} |
上游赋值节点的输出结果为一维数组时,获取具体某列数据。 |
内置变量取值案例
- 案例1
上游赋值节点为Shell节点,最后一条输出结果为
2021-03-28,2021-03-29,2021-03-30,2021-03-31,2021-04-01
,此时,各变量的取值如下:说明 由于输出结果为一维数组,数组元素个数为5(逗号分隔每个元素),因此for-each总遍历次数为5。内置变量 第1次循环遍历的取值 第2次循环遍历的取值 ${dag.loopDataArray}
2021-03-28,2021-03-29,2021-03-30,2021-03-31,2021-04-01
${dag.foreach.current}
2021-03-28
2021-03-29
${dag.offset}
0 1 ${dag.loopTimes}
1 2 ${dag.foreach.current[3]}
2021-03-30
- 案例2
上游赋值节点为ODPS SQL节点,最后一条select语句查询出两条数据:
此时,各变量的取值如下:+----------------------------------------------+ | uid | region | age_range | zodiac | +----------------------------------------------+ | 0016359810821 | 湖北省 | 30~40岁 | 巨蟹座 | | 0016359814159 | 未知 | 30~40岁 | 巨蟹座 | +----------------------------------------------+
说明 由于输出结果为二维数组,数组行数为2,因此for-each总遍历次数为2。内置变量 第1次循环遍历的取值 第2次循环遍历的取值 ${dag.loopDataArray}
+----------------------------------------------+ | uid | region | age_range | zodiac | +----------------------------------------------+ | 0016359810821 | 湖北省 | 30~40岁 | 巨蟹座 | | 0016359814159 | 未知 | 30~40岁 | 巨蟹座 | +----------------------------------------------+
${dag.foreach.current}
0016359810821,湖北省,30~40岁,巨蟹座
0016359814159,未知,30~40岁,巨蟹座
${dag.offset}
0 1 ${dag.loopTimes}
1 2 ${dag.foreach.current[0]}
0016359810821
0016359814159
${dag.loopDataArray[1][0]}
0016359814159