概述
参数配置完成后,需要在任务代码中通过特定语法引用参数值。不同任务类型使用不同的引用方式:
任务类型 | 引用语法 | 说明 |
Notebook | dlcutils.widgets.get('param_name') | 返回字符串类型的参数值 |
SQL | ${param_name} | 运行时直接替换为参数值 |
在 Notebook 中使用参数
引用语法
value = dlcutils.widgets.get('param_name')
param_name:参数名,对应工作流参数或任务参数中定义的 Key。返回值为字符串类型。如需数值类型,请在代码中显式转换。
示例
引用工作流参数
假设在工作流参数中定义了:
dp_data_dt = {{workflow.start_time.iso_date}}# 获取参数值dt = dlcutils.widgets.get('dp_data_dt')print(dt)# 输出: 2026-06-11# 如需数值,显式转换batch_size = int(dlcutils.widgets.get('batch_size'))
引用任务参数
假设在任务参数中定义了:
task_param = {{tasks.upstream_sql.output.first_row.col_a}}col_a_value = dlcutils.widgets.get('task_param')print(col_a_value)# 输出: 上游 SQL 第一行 col_a 的值
调试运行与调度运行的区别
场景 | 行为 |
Studio 调试运行 | 如果参数未定义,弹窗提示用户手动填写参数值。 |
Workflow 调度运行 | 系统自动解析参数值,未定义的参数返回空字符串。 |
在 SQL 中使用参数
引用语法
${param_name}
运行时
${param_name} 会被直接替换为参数值(字符串替换)。示例
引用工作流参数
假设在工作流参数中定义了:
dp_data_dt = {{workflow.start_time.iso_date}}SELECT *FROM my_tableWHERE dt = '${dp_data_dt}';-- 运行时替换为: WHERE dt = '2026-06-11'
引用任务参数
假设在任务参数中定义了:
target_db = my_databaseUSE ${target_db};SELECT COUNT(*) FROM orders;-- 运行时替换为: USE my_database;
多参数组合
SELECT *FROM ${target_db}.${target_table}WHERE dt = '${dp_data_dt}'AND env = '${env}';
调试运行与调度运行的区别
场景 | 行为 |
Studio 调试运行 | 如果参数未定义,弹窗提示用户手动填写参数值。 |
Workflow 调度运行 | 系统自动解析;未定义的参数替换为空字符串,可能导致 SQL 语法错误。 |
在其他任务类型中使用参数
任务类型 | 引用语法 |
离线数据接入 | ${param_name} |
条件节点 | ${param_name} |
For Each 循环 | ${param_name} |
嵌套工作流(Run Job) | ${param_name} |
最佳实践
1. 在工作流参数中封装系统内置参数
推荐将系统内置参数封装为语义明确的业务参数,代码中只引用业务参数名。
# 工作流参数定义dp_data_dt = {{workflow.start_time.iso_date}}
-- SQL 中引用(推荐)WHERE dt = '${dp_data_dt}'-- 不推荐直接在代码中写内置参数
# Notebook 中引用(推荐)dt = dlcutils.widgets.get('dp_data_dt')
好处:
参数名语义明确,代码可读性高。
统一在工作流参数中管理,修改一处即可生效。
日志中参数值可追溯。
2. 基于 trigger 时间做偏移计算
常见场景:需要用 trigger 时间 -1 天作为分区时间(T+1 场景)。
注意
系统内置参数
{{workflow.trigger.time.iso_date}} 不支持直接在模板语法中做偏移运算,需要在代码中自行计算。前置步骤:在工作流参数中定义 trigger 日期
trigger_date = {{workflow.trigger.time.iso_date}}
方式一:在 SQL 中使用函数计算
-- 工作流参数已定义: trigger_date = {{workflow.trigger.time.iso_date}}-- 使用 DATE_SUB 函数将 trigger 日期减 1 天作为分区时间SELECT *FROM dw.user_dailyWHERE dt = DATE_SUB('${trigger_date}', INTERVAL 1 DAY);-- 如果 trigger 时间为 2026-06-12,则等价于: WHERE dt = '2026-06-11'
如果引擎不支持
DATE_SUB,也可以使用 DATE_ADD:WHERE dt = DATE_ADD('${trigger_date}', INTERVAL -1 DAY);
方式二:在 Notebook 代码中计算偏移
from datetime import datetime, timedelta# 获取工作流参数中的 trigger 日期trigger_date = dlcutils.widgets.get('trigger_date')# trigger_date 值示例: '2026-06-12'# 计算前一天作为分区时间dt_obj = datetime.strptime(trigger_date, '%Y-%m-%d')partition_date = (dt_obj - timedelta(days=1)).strftime('%Y-%m-%d')print(partition_date)# 输出: 2026-06-11# 后续使用 partition_date 进行数据读写spark.sql(f"SELECT * FROM dw.user_daily WHERE dt = '{partition_date}'")
3. 注意字符串类型
参数值始终为字符串类型。在 SQL 中引用时需注意是否需要加引号:
-- 字符串类型字段:加引号WHERE dt = '${dp_data_dt}'-- 数值类型字段:不加引号(参数值本身是数字字符串)WHERE id = ${target_id}
在 Notebook 中需显式类型转换:
# 字符串参数env = dlcutils.widgets.get('env')# 需要数值时batch_size = int(dlcutils.widgets.get('batch_size'))threshold = float(dlcutils.widgets.get('threshold'))
4. 设置合理的默认值
在开发调试阶段,建议为参数提供默认值,避免调试运行时反复手动输入:
import os# 在 Notebook 中,可以先尝试获取参数,获取不到时使用默认值dt = dlcutils.widgets.get('dp_data_dt')if not dt:dt = '2026-06-11' # 开发用默认值
使用限制
参数值始终为字符串类型,代码中如需其他类型请显式转换。
${param_name} 在 SQL 中是纯文本替换,不会自动加引号。参数名区分大小写:
dp_data_dt 和 DP_DATA_DT 是两个不同的参数。未定义的参数在调度运行时替换为空字符串,可能导致 SQL 语法错误。
常见问题
Q1:Notebook 中
dlcutils.widgets.get 返回 None 或空字符串?检查参数名是否拼写正确(区分大小写)。
检查是否在工作流参数或任务参数中定义了该参数。
如果是调试运行,检查是否在弹窗中填写了参数值。
Q2:SQL 中
${param} 没有被替换?确认参数名拼写正确。
确认该参数已在工作流参数或任务参数中定义。
如果是在 Studio 中调试,需在弹窗中填写参数值。
Q3:如何在 SQL 中引用上游任务的输出?
不能直接在 SQL 代码中使用
{{tasks.<name>.values.<key>}}。正确做法:1. 在任务参数中定义:
my_param = {{tasks.<name>.values.<key>}}2. 在 SQL 中引用:
${my_param}