Databricks中Spark DataFrame转JSON为CSV遇数组及_corrupt_string问题求助
你的问题核心是CSV不支持嵌套的数组数据类型,而你的JSON里Data字段是一个数组对象,直接转CSV就会触发这个错误。另外_corrupt_string字段一般是Spark读取JSON时格式解析异常导致的,我们可以通过调整读取选项和数据处理来解决这两个问题。
先看优化后的完整代码,我会逐段解释:
# 直接用Spark读取JSON,不需要用Python原生json模块处理,Spark能直接解析嵌套结构 df = spark.read.option("multiLine", "true").json("dbfs:/FileStore/tables/ABC.json") # 第一步:展开Data数组列,将嵌套的数组转为多行数据 from pyspark.sql.functions import explode df_exploded = df.select("Table", explode("Data").alias("data")) # 第二步:将嵌套的data结构体展开为扁平列 df_flattened = df_exploded.select("Table", "data.*") # 第三步:移除_corrupt_string字段(如果存在),可以用drop方法直接删除 if "_corrupt_string" in df_flattened.columns: df_flattened = df_flattened.drop("_corrupt_string") # 最后保存为CSV df_flattened.write.mode("overwrite").option("header", "true").csv("dbfs:/FileStore/tables/ABC_1.csv")
关键问题拆解
为什么原代码报错?
你原来用Python原生json模块读写JSON的步骤是多余的,而且最终生成的ABC_1.json还是保留了Data数组字段。CSV是扁平的表格格式,Spark的CSV数据源无法直接处理数组类型,必须先把数组展开成多行,再把嵌套的结构体拆成单独的列。如何处理数组类型?
使用explode函数把Data数组里的每个元素拆成单独的行,然后用select("data.*")把结构体里的aa、bb字段展开成独立的列,这样整个DataFrame就变成了扁平结构,完全符合CSV的格式要求。如何移除_corrupt_string?
这个字段通常是因为Spark读取JSON时没有开启multiLine选项(你的JSON是单行完整结构,需要告诉Spark按单行解析),或者JSON格式有残缺。我们读取时添加option("multiLine", "true")可以避免大部分解析错误;如果还是出现这个字段,直接用drop("_corrupt_string")删除即可。
另外提个小建议:Databricks里推荐用spark Session而不是sqlContext,前者是更现代、功能更完善的API。
内容的提问来源于stack exchange,提问作者pythonUser

