DataWorks为您提供循环节点(do-while节点),您可以重新编排do-while节点内部的业务流程,将需要循环执行的逻辑写在节点内,再编辑end循环判断节点来控制是否退出循环。同时您也可以结合赋值节点来循环遍历赋值节点传递的结果集。本文为您介绍do-while节点的组成与应用逻辑。

节点组成

DataWorks的do-while节点是包含内部节点的一种特殊节点,您在创建完成do-while节点时,同时也自动创建完成了三个内部节点:start节点(循环开始节点)、sql节点(循环任务节点)、end节点(循环结束判断节点),通过内部节点组织成内部节点流程,实现任务的循环运行。循环节点如上图所示:
  • start节点

    是内部节点的开始节点,不承载具体的任务代码。

  • sql节点
    DataWorks默认为您创建好了一个SQL类型的内部任务运行节点,您也可以删除默认的sql节点后,自定义内部循环任务的运行节点。
    • 您的循环任务是SQL类型的任务,则可以直接双击默认的sql节点,进入节点的代码开发页面开发循环任务代码。
    • 您的循环任务比较复杂,您可以在内部节点流程中新建其他任务节点,并根据实际情况重新构建节点的运行流程。
      通常循环任务的业务流程会与赋值节点、分支节点、归并节点联合使用,典型应用场景说明请参见典型应用:与赋值节点联合使用
      说明 自定义循环任务节点时,您可以删除内部节点间的依赖关系,重新编排循环节点内部业务流程,但需要分别将start节点end节点分别作为do-while节点内部业务流程的首末节点。
  • end节点
    • end节点是do-while节点的循环判断节点,来控制do-while节点循环次数,其本质上是一个赋值节点,输出truefalse两种字符串,分别代表继续下一个循环和不再继续循环。
    • end节点支持使用ODPS SQL、SHELL和Python(Python2)三种语言进行循环判断代码开发,同时do-while节点为您提供了便利的内置变量,便于您进行end代码开发。内置变量的介绍请参见内置变量变量取值案例,不同语言开发的样例代码请参见案例1:end节点代码样例

使用限制与注意事项

  • 循环支持
    • 仅DataWorks标准版及以上版本支持使用do-while节点。
    • do-while节点最多支持循环128次,end节点控制循环次数时,如果超过了128次,则运行会报错。
  • 内部节点
    • 自定义循环任务节点时,您可以删除内部节点间的依赖关系,重新编排循环节点内部业务流程,但需要分别将start节点end节点分别作为do-while节点内部业务流程的首末节点。
    • 在do-while节点的内部节点使用分支节点进行逻辑判断或者结果遍历时,需要同时使用归并节点。
    • do-while节点的内部节点end节点在代码开发时,不支持添加注释。
  • 调测运行
    • DataWorks为标准模式时,不支持在DataStudio界面直接测试运行do-while节点。

      如果您想测试验证do-while节点的运行结果,您需要将包含do-while节点的任务发布提交到运维中心,在运维中心页面运行do-while节点任务。如果您在do-while节点内使用了赋值节点传递的值,请在运维中心测试时,同时运行赋值节点和循环节点。

    • 在运维中心查看do-while节点的执行日志时,您需要右键实例,单击查看内部节点来查看内部节点的执行日志。

典型应用:与赋值节点联合使用

do-while节点常常与赋值节点联合使用,如下图所示。赋值节点与赋值节点联合使用时:
  • 您需要将赋值节点的输出作为赋值节点的本节点输入,且与赋值节点做好上下游依赖关系的配置,其他配置注意事项请参见案例2:与赋值节点联合使用
  • 与赋值节点联合使用时,可以使用一些内置变量来获取当前已循环次数、赋值参数值等循环变量值,详情请参见内置变量

内置变量

DataWorks的do-while节点,通过内部节点来实现循环运行任务,每次任务循环运行时,您可以通过一些内置的变量来获取当前已循环次数和偏移量。
内置变量 含义 取值
${dag.loopTimes} 当前已循环次数 第一次循环为1、第二次为2、第三次为3…第n次为n。
${dag.offset} 偏移量 第一次循环为0、第二次为1、第三次为2…第n次为n-1。
如果您联合使用了赋值节点,则还可以通过以下方式来获取赋值参数值和循环变量参数。
说明 以下以变量示例中,input是do-while节点中自定义的本节点输入参数名称,实际使用时,需替换为您真实的名称。
内置变量 含义
${dag.input} 上游赋值节点传递的数据集。
${dag.input[${dag.offset}]} 循环节点内部获取当前循环的数据行。
${dag.input.length} 循环节点内部获取数据集长度。

变量取值案例

  • 案例1
    上游赋值节点为shell节点,最后一条输出结果为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  | 湖北省 | 30~40岁   | 巨蟹座 |
    | 0016359814159  | 未知   | 30~40岁   | 巨蟹座 |
    +----------------------------------------------+
    此时,各变量的取值如下:
    内置变量 第1次循环时取值 第2次循环时取值
    ${dag.input}
    +----------------------------------------------+
    | uid            | region | age_range | zodiac |
    +----------------------------------------------+
    | 0016359810821  | 湖北省 | 30~40岁   | 巨蟹座 |
    | 0016359814159  | 未知   | 30~40岁   | 巨蟹座 |
    +----------------------------------------------+
    ${dag.input[${dag.offset}]} 0016359810821,湖北省,30~40岁,巨蟹座 0016359814159,未知,30~40岁,巨蟹座
    ${dag.input.length} 2
    说明 二维数组的行数为数据集长度,当前赋值节点输出的二维数组行数为2。
    ${dag.input[0][1]
    说明 二维数组的第一行第一列的取值。
    0016359810821
    ${dag.loopTimes} 1 2
    ${dag.offset} 0 1

案例1:end节点代码样例

end节点支持使用ODPS SQL、SHELL和Python(Python2)三种语言进行循环判断代码开发,以下为您示例三种不同语言下,典型的代码样例。
  • 使用ODPS SQL语言时:
    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';

    end节点示例代码中将表行数和迁移量与固定值比较,来限制do-while节点整体的循环次数。

  • 使用SHELL语言时:
    if [ ${dag.loopTimes} -lt 5 ];
    then
         echo "True"
    else
         echo "False"
    fi

    将循环次数${dag.loopTimes}和5进行比较,来限制do-while节点整体的循环次数。

    例如:第一次循环${dag.loopTimes}的值为1、第二次为2,以此类推,第五次为5。至此end节点的输出结果为false,do-while节点退出循环。

  • 使用Python(Python2)语言时:
    if ${dag.loopTimes}<${dag.input.length};
       print True;
    else
       print False;
    # 如果end节点输出True,则继续下一个循环。
    # 如果end节点输出False,则终止循环。

    代码中把循环次数${dag.loopTimes}和赋值节点传递的数据集行数进行比较,来限制do-while节点整体的循环次数。

案例2:与赋值节点联合使用

do-while节点与赋值节点联合使用时,典型的应用场景和注意事项如下所示。赋值节点
应用场景 注意事项 配置案例
使用do-while节点进行循环任务时,内部节点的循环任务在每一次循环时,需要获取使用上游节点(up节点)的输出参数时,此时可以使用赋值节点(assign_node)。
  • 依赖关系

    do-while节点需要依赖上游赋值节点(assign_node)。

    说明 如上图所示,依赖关系是do-while节点依赖赋值节点,而非do-while的内部循环任务节点(sql节点)依赖赋值节点。
  • 上下文参数
    • 赋值节点需将输出参数作为赋值节点(assign_node)的本节点输出参数
    • do-while的内部循环任务节点(sql节点)需将赋值节点的输出参数添加为本节点输入参数
      说明 上下文关系设置,需设置内部的循环任务节点,而非do-while节点。
赋值节点配置案例

案例3:与分支节点、归并节点联合应用

分支节点归并节点联合应用时,典型的应用场景和注意事项如下所示。典型应用
应用场景 注意事项
do-while节点内部需要进行逻辑判断或者结果遍历时,此时可以在do-while节点的内部节点中自定义循环任务节点,并使用分支节点(branch_node和归并节点(merge_node))。 在do-while节点内部,分支节点(branch_node)需要和归并节点(merge_node)同时使用。