Azure Data Factory无法读取Databricks作业/笔记本生成的Parquet文件
问题根因
报错提到的txn列并非业务代码手动创建,是Databricks写入Parquet文件时自动注入的内部事务元数据列:
- 该列为Struct嵌套非基元类型,存储写入操作的事务ID、提交时间戳、作业ID等内部溯源信息
- Databricks自带的Parquet读取器默认会自动屏蔽这类内部列,因此在Databricks环境内查询schema、读写数据都完全感知不到该列的存在,业务逻辑运行无异常
- ADF的原生Parquet解析组件没有内置这类Databricks内部列的过滤逻辑,扫描到未在业务schema中声明的嵌套类型列时,就会抛出非基元类型不支持的错误
该隐式列通常在两类场景下出现:
- 直接读取Delta Lake表底层存储路径下的原始Parquet文件,而非通过Delta协议接口读取表数据
- 使用Databricks Runtime 9.1及以上版本写入普通Parquet文件时,默认开启了事务溯源标记配置,自动注入了该元数据列
可行解决方案
按落地成本从低到高排序:
- 调整ADF侧读取容错配置
打开ADF Parquet数据集配置中容错板块的跳过不兼容的行/列开关,ADF解析时会自动忽略这个无业务意义的内部列,不会再触发类型报错,读取到的业务数据、字段结构完全正常。 - 修改Databricks侧写入配置,禁止注入元数据列
在Parquet写入作业/笔记本的初始化环节添加Spark配置,关闭内部事务列自动注入逻辑:
配置生效后新写入的Parquet文件将不再携带spark.conf.set("spark.databricks.io.parquet.writeMetadataColumns", "false")txn隐式列,可被所有标准Parquet解析引擎正常读取。注意该配置仅对生效后新生成的文件有效,历史存量文件不会被自动修改。 - 修正读取路径(针对误读Delta表底层文件的场景)
不要直接读取Delta表存储目录下分区子路径中的原始Parquet文件。如果需要将Delta表数据共享给外部服务读取,可以通过Databricks生成symlink清单供外部服务识别,或是将Delta表数据显式写入独立的普通Parquet存储路径后再供ADF读取。 - 修复历史存量文件
对于已经生成的携带txn列的存量Parquet文件,可直接在Databricks中读取对应路径的数据(Databricks会自动过滤掉内部元数据列,返回的DataFrame仅包含业务字段),在关闭元数据列注入配置的前提下重新写入覆盖原路径即可。
内容的提问来源于stack exchange,提问作者Deepak
相关产品推荐
相关产品推荐

