Spark Scala读取含逗号引号嵌套CSV字段全null处理方法
问题根因
读取结果全为null是3个配置错误共同导致的:
- 自定义Schema与CSV实际结构不匹配:代码中注释掉了
name字段的定义,Schema仅包含2个字段,但CSV实际有3列;同时CSV第三列表头为addresses(带复数s),与Schema中定义的address字段名不一致。 - CSV表头存在多余空格:示例CSV的表头逗号后带空格,默认配置下解析出的列名为
name、age(前带空格)、addresses(前带空格),与Schema中定义的无空格字段名完全无法匹配。 - 未显式指定引号转义规则:虽然Spark CSV默认以双引号作为字段包裹符,但显式配置可以避免不同环境默认配置差异导致引号内逗号被误识别为字段分隔符。
正确实现方案
按照如下配置修改代码,即可实现双引号包裹的带逗号地址完整保留在单独一列:
- 补全Schema定义,保证字段数量与CSV列数一致,字段名与表头对齐
- 新增CSV读取参数,忽略字段/表头前后空格,显式指定双引号为字段包裹符
- 读取完成后可按需重命名列名,调整展示规则避免长文本截断
修正后可运行代码
import org.apache.spark.sql.SparkSession import org.apache.spark.sql.types.{IntegerType, StringType, StructField, StructType} val spark = SparkSession .builder() .appName("FirstApp") .master("local") .getOrCreate() spark.sparkContext.setLogLevel("ERROR") // 补全全量字段,字段名和CSV表头对齐 val customSchema = StructType(Array( StructField("name", StringType, true), StructField("age", IntegerType, true), StructField("addresses", StringType, true) )) val data = spark.read .option("header", true) // 忽略表头、字段值前后的空格 .option("ignoreLeadingWhiteSpace", value = true) .option("ignoreTrailingWhiteSpace", value = true) // 显式指定双引号为字段包裹符,引号内逗号不做分隔符 .option("quote", "\"") .schema(customSchema) .format("csv") .load("user.csv") // 如需把列名从addresses改为address,加这行重命名即可 .withColumnRenamed("addresses", "address") // show传入false表示不截断字段内容,长地址可以完整展示 data.show(false)
运行输出结果
+----+---+--------------------------+ |name|age|address | +----+---+--------------------------+ |Ram |30 |France,street name,75000 | |Hari|20 |India,karnataka,Bng,856000| +----+---+--------------------------+
内容的提问来源于stack exchange,提问作者rasmi
相关产品推荐
相关产品推荐

