Azure Data Factory Data Flow用Cached Lookup做动态列映射时Select转换报错
问题原因
缓存填充与映射执行顺序冲突
你当前定义的数据流中,元数据读取、过滤、生成缓存的分支,和源数据读取、字段映射的分支是并行执行的。你给缓存Sink设置的saveOrder: 1仅能控制多个Sink节点的写入先后,无法改变上游转换的执行时序。当MapColumns节点的Select转换尝试调用缓存做Lookup时,缓存还未完成元数据写入,为空的缓存会触发无明确提示的运行时错误。规则映射表达式语法错误
你在Select转换的规则映射中写的表达式存在两处逻辑问题:
- match条件中的
name变量为未定义变量,你需要匹配的是当前遍历到的源列名,应该用内置变量$$代替name - 列映射的赋值逻辑写反,ADF数据流的mapColumn规则要求左侧为目标列名、右侧为源列值,你直接把Lookup返回的字符串作为左值,不符合语法要求,需要用
toName()函数将返回的字符串转换为合法的列名标识。
- 无Lookup空值兜底逻辑
如果源端存在未在元数据表中配置映射规则的列,Lookup函数会返回null值,无兜底判断的情况下会直接触发空引用报错。
修复方案
- 调整数据流执行依赖:在
MapColumnsSelect转换前增加一个虚拟派生列节点,派生列的值随便引用缓存的Lookup结果(比如写个常量CacheFieldsMap#lookup('test'),值不会实际使用),强制让映射分支必须等待缓存分支执行完成再运行。 - 修正规则映射表达式为:
each(match(!isNull(CacheFieldsMap#lookup($$).targetField)), toName(CacheFieldsMap#lookup($$).targetField) = $$ )
- 可选增加空值兜底逻辑,避免偶发的元数据缺失导致任务失败:
each(match(!isNull(CacheFieldsMap#lookup($$).targetField)), toName(coalesce(CacheFieldsMap#lookup($$).targetField, $$)) = $$ )
内容的提问来源于stack exchange,提问作者Fabio Carello
相关产品推荐
相关产品推荐

