Scala Spark执行union报错"Union要求参与表列数相同"问题求助
Spark Scala union操作报错排查解决方案
核心报错原因
你遇到的列数不匹配报错,主要由以下几个问题共同导致:
- 初始空DataFrame无匹配结构:
spark.emptyDataFrame默认是0列的无结构DataFrame,而你通过select A.* , B.*得到的res是两个2列DF join后的4列结构,首次执行union时两边列数不一致,直接触发错误。 - 变量声明不符合语法要求:你用
val声明的adf是Scala不可变变量,循环内直接执行adf = adf.union(res)本身会先触发编译层面的赋值错误,需要改为var声明。 - 方法拼写错误:
creatOrReplaceTempView拼写有误,正确方法名为createOrReplaceTempView。
修复方案
方案1:调整初始DF结构+可变变量实现
// 先定义与res结构一致的空DF,或在第一次循环时直接赋值 var adf: Option[DataFrame] = None for (i <- 0 until 10 ) { val df1 = spark.read.format("csv").load("c:\\file.txt") val df2 = spark.read.format("csv").load("c:\\file.txt") df1.createOrReplaceTempView("tab1") df2.createOrReplaceTempView("tab2") val res = spark.sql("Select A.* , B.* from tab1 a join tab2 b on a.id = b.id") adf = adf match { case None => Some(res) case Some(existingDf) => Some(existingDf.union(res)) } } adf.getOrElse(spark.emptyDataFrame).show()
方案2:更符合Scala风格的无可变变量实现
// 把所有生成的res放到集合中,统一执行union val dfList = (0 until 10).map { i => val df1 = spark.read.format("csv").load("c:\\file.txt") val df2 = spark.read.format("csv").load("c:\\file.txt") df1.createOrReplaceTempView("tab1") df2.createOrReplaceTempView("tab2") spark.sql("Select A.* , B.* from tab1 a join tab2 b on a.id = b.id") } // 批量union所有DF val adf = dfList.reduce(_ union _) adf.show()
优化建议
- 重复读取的文件可以提前加载到内存中,避免循环内反复触发磁盘IO,大幅提升执行效率。
- union操作默认不校验列顺序,仅校验列数和列类型,建议执行union前统一对齐列顺序,避免出现数据错位问题。
内容的提问来源于stack exchange,提问作者VnS
相关产品推荐
相关产品推荐

