PySpark读取JSON时自定义嵌套Schema未生效问题
问题根因
该现象不是PySpark的固有功能限制,是Spark 3.2.0之前版本JSON解析模块的已知bug,触发规则完全匹配你遇到的场景:
- 同一父Struct下存在多个子Struct字段,这些子Struct的字段数量、字段类型完全一致,仅字段名不同
- 这些子Struct实例的所有字段值完全相等
触发bug时,Spark Catalyst优化器会错误判定这些子Struct是同构可复用对象,解析时直接按Schema定义的字段位置赋值,完全忽略JSON本身的键名匹配:
- 你的原始数据里
rear、front、keepAssist三个子Struct都是2个Boolean型字段,且所有字段值均为false,刚好满足触发条件,因此后解析的keepAssist被错误套用了先出现的rear/front的字段名alarm、muted - 修改
keepAssist下任意一个字段值为true后,同构Struct的值不再完全一致,错误的复用逻辑不会触发,解析回归按键名匹配的正常流程,结果就正确 - 调整自定义Schema中
lane和parkAssist的顺序后,错误映射的对象同步转移,就是按位置赋值的直接表现
修复方案
可根据实际环境选择以下方案:
- 升级Spark版本到3.2.0及以上:该bug在3.2.0版本已正式修复,升级后原有读取代码无需修改即可得到正确结果
- 大版本无法升级时,绕过
read.json的内置优化逻辑:先将JSON文件读为纯文本,再通过from_json函数显式传入自定义Schema解析,即可避开错误的结构复用逻辑,示例代码:
from pyspark.sql.functions import from_json, col # 读取整段JSON文本 raw_df = spark.read.option("multiline", "true").text("///myfile.json") # 按指定schema解析 parsed_df = raw_df.select(from_json(col("value"), custom_schema).alias("data")) # 提取结果 result = parsed_df.select("data.*").first().asDict()
- 临时调试场景可添加读取选项
.option("timestampFormat", "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"),强制优化器跳过同构Struct复用判断,该方案稳定性不足,不推荐生产环境使用。
内容的提问来源于stack exchange,提问作者Valéry
相关产品推荐
相关产品推荐

