Databricks中schema_of_json无法推断JSON的data字段问题
问题原因
Spark的schema_of_json函数推断JSON Schema时,依赖示例JSON中的实际键值对数据确定字段类型与结构。你的示例JSON里data字段下的所有子字段都是空对象{},没有可用于推断类型的内容,因此schema_of_json直接忽略了整个data字段,仅保留有明确字符串值的_file_path,最终导致解析后丢失data部分。
解决方案
以下是几种无需手动指定完整Schema即可保留data字段的方法:
方法1:用MapType解析动态结构
利用MapType容纳data下的动态空对象结构,无论子字段是否为空,都能完整保留层级:
from pyspark.sql.functions import from_json, col from pyspark.sql.types import StructType, StructField, MapType, StringType # 定义顶层Schema,data字段用嵌套MapType适配动态空对象 top_level_schema = StructType([ StructField("data", MapType(StringType(), MapType(StringType(), StringType()))), StructField("_file_path", StringType()) ]) temp_df = spark.read.table('tabl').select('_rescued_data') temp_df = temp_df.withColumn('_rescued_data_st', from_json(col('_rescued_data'), top_level_schema))
该方式会将data下的所有空对象解析为空Map结构,完整保留原始JSON的层级。
方法2:修改示例JSON辅助Schema推断
通过修改示例JSON中的空对象,添加临时键值对让schema_of_json识别字段结构,后续即使实际数据是空对象,也能保留字段:
from pyspark.sql.functions import schema_of_json, lit, col, from_json temp_df = spark.read.table('tabl').select('_rescued_data') sample = temp_df.filter(col('_rescued_data').isNotNull()).limit(1).collect() sample_json = sample[0]['_rescued_data'] # 将示例中的空对象替换为带临时字段的结构,帮助Spark推断Schema modified_sample = sample_json.replace("{}", '{"temp_key": ""}') inferred_schema = schema_of_json(lit(modified_sample)) temp_df = temp_df.withColumn('_rescued_data_st', from_json(col('_rescued_data'), inferred_schema))
这种方法生成的Schema会包含data及其所有子字段,实际空对象解析后对应字段值为null。
方法3:直接提取并保留原始JSON片段
如果不需要解析data的内部结构,仅需保留该字段的原始JSON字符串,可使用get_json_object直接提取:
from pyspark.sql.functions import get_json_object, col temp_df = spark.read.table('tabl').select('_rescued_data') temp_df = temp_df.withColumn('data', get_json_object(col('_rescued_data'), '$.data')) .withColumn('_file_path', get_json_object(col('_rescued_data'), '$._file_path'))
内容的提问来源于stack exchange,提问作者practicalGuy
相关产品推荐
相关产品推荐

