You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spark Scala读取Parquet后无法去除列名中空格问题求助

问题原因
  • 你之前尝试的方案全部报错,是因为Spark默认在解析Parquet文件Schema时就会校验列名字符合法性,只要你读取数据后调用columns/withColumnRenamed/toDF等任何需要访问Schema的方法,都会直接触发校验抛出异常,根本没执行到重命名的逻辑。
可行方案

方案1:开启兼容配置后重命名(适合列多、不想手动写Schema的场景)

创建SparkSession时添加允许列名含非法字符的兼容配置,之后就可以正常用批量重命名逻辑:

import org.apache.spark.sql.SparkSession

val spark = SparkSession.builder()
  .appName("process-parquet-with-space-column")
  // 核心配置:允许列名包含非法特殊字符
  .config("spark.sql.legacy.allowInvalidCharInColumnName", "true")
  .getOrCreate()

// 读取文件
val df = spark.read.parquet("s3://tvsc-lumiq-edl/raw-v2/LMSDB/DESUSR/TBL_DES_SLA_MIS1")

// 批量替换空格为下划线后重命名
val newCols = df.columns.map(c => c.replaceAll("\\s+", "_"))
val cleanDf = df.toDF(newCols: _*)

// 后续正常使用cleanDf即可

如果是Spark 2.x版本找不到上述配置,可以替换为:

.config("spark.sql.parser.escapedStringLiterals", "true")

方案2:手动指定Schema读取(适合列少、不想改全局配置的场景)

直接按照原文件的字段顺序和类型自定义Schema,读取时直接映射为无空格的列名,一步到位不需要额外重命名:

import org.apache.spark.sql.types._

// 按照原Parquet文件的字段顺序、类型、可空属性定义Schema,列名直接写替换后的无空格版本
val customSchema = StructType(Seq(
  StructField("dms_timestamp", StringType, nullable = true),
  StructField("BRANCH_NAME", StringType, nullable = true),
  StructField("BRANCH_CODE", StringType, nullable = true),
  StructField("DEALER_NAME", StringType, nullable = true),
  StructField("DEALER_CODE", StringType, nullable = true),
  StructField("DEALER_CATEGORY", StringType, nullable = true),
  StructField("PRODUCT", StringType, nullable = true),
  StructField("CREATION_DATE", StringType, nullable = true),
  StructField("CHANNEL_TYPE", StringType, nullable = true),
  StructField("DELAY_DAYS", StringType, nullable = true)
))

// 读取时直接指定自定义Schema
val df = spark.read.schema(customSchema).parquet("s3://tvsc-lumiq-edl/raw-v2/LMSDB/DESUSR/TBL_DES_SLA_MIS1")

内容的提问来源于stack exchange,提问作者whatsinthename

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 06:06:01