Scala中如何解决‘not a valid external type’类型不匹配错误?
问题分析
报错核心信息java.lang.Integer is not a valid external type for schema of double表明:Spark根据指定Schema解析Row数据时,发现某位置的实际数据类型为Integer,但Schema定义的是Double,二者类型不匹配。结合代码和报错,存在两个关键问题:
1. 对象引用拼写错误
你定义的对象是object xyzz,但创建DataFrame时引用的是xyz.df(少了一个字母z)。如果xyz是其他已存在的对象,且其df的第一个元素为Integer类型,就会触发类型不匹配错误。
2. Assert语句比较逻辑错误
test.where(...).select(...).collect()(0)返回的是Row对象,直接和Double值10528.53994比较永远不会相等,必须提取Row中的具体数值再做比较。
修复后的代码
object xyzz { val df = Seq( Row(10528.53994, 20232, "abc") ) } val schema: StructType = StructType( Seq( StructField("AMOUNT", DoubleType), StructField("PERIOD", IntegerType), StructField("ID", StringType) ) ) // 修正对象引用拼写错误 val test = spark.createDataFrame(spark.sparkContext.parallelize(xyzz.df), schema) assert( // 提取Row中的Double值再进行比较 test.where(col("ID") === lit("abc")).select(col("AMOUNT")).collect()(0).getAs[Double]("AMOUNT") == 10528.53994 )
额外优化建议
- 避免硬编码索引提取Row元素,通过字段名获取更安全:
getAs[Double]("AMOUNT") - 浮点数直接用
==比较可能存在精度误差,建议使用近似比较:val targetAmount = 10528.53994 val actualAmount = test.where(col("ID") === lit("abc")).select(col("AMOUNT")).collect()(0).getAs[Double]("AMOUNT") assert(math.abs(actualAmount - targetAmount) < 1e-6)
内容的提问来源于stack exchange,提问作者djm
相关产品推荐
相关产品推荐

