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

问询SPARK-25177关联修复PR是否已纳入Spark正式版本

SPARK-25177问题修复版本确认及临时解决方案

问题说明

使用基于Spark 3.3.0的AWS Glue 4时,遭遇SPARK-25177问题:当decimal类型的scale>6时,0值会以科学计数法输出,导致DataFrame写入外部数据库失败。已在AWS Glue 4中验证该问题未修复,关联修复PR#22171已合并至Spark master分支,需确认该修复是否已进入Spark正式发布版本。

重现代码

spark.sql("create table test (a decimal(10,7), b decimal(10,6), c decimal(10,8))")
spark.sql("insert into test values(0, 0,0)")
spark.sql("insert into test values(1, 1, 1)")
spark.table("test").show()

执行结果:

+---------+--------+----------+
| a| b| c|
+---------+--------+----------+
| 0E-7|0.000000| 0E-8| // scale>6时,0值以科学计数法显示
|1.0000000|1.000000|1.00000000|
+---------+--------+----------+

修复版本确认

PR#22171的修复逻辑已合并至Spark master分支,该修复首次正式发布在Spark 2.4.3版本中。但部分定制化Spark发行版(如AWS Glue 4基于的Spark 3.3.0)可能未包含该修复,或存在回归情况。
若需确认特定Spark版本是否包含该修复,可通过两种方式:

  • 查看对应版本的Release Notes,搜索SPARK-25177关键词;
  • 检查该版本源码中Decimal.toString()方法的实现,确认是否针对scale>6的0值做了非科学计数法的处理。

临时解决方案

自定义UDF处理0值格式

创建自定义UDF,判断decimal值是否为0,若是则输出对应scale的固定格式字符串,否则保留原格式:

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

val formatDecimalZero = udf((value: java.math.BigDecimal, scale: Int) => {
  if (value.compareTo(java.math.BigDecimal.ZERO) == 0) {
    s"0.${"0" * scale}"
  } else {
    value.toPlainString
  }
})

// 示例:处理test表中scale=7的a列、scale=8的c列
val processedDF = spark.table("test")
  .withColumn("a", formatDecimalZero(col("a"), lit(7)))
  .withColumn("c", formatDecimalZero(col("c"), lit(8)))

processedDF.show()

执行后0值将以非科学计数法显示,可正常写入外部数据库。

转换为字符串时使用toPlainString

在将decimal列转换为字符串时,调用BigDecimal的toPlainString方法,避免科学计数法输出。该方法会返回不带指数的字符串表示,适用于所有decimal值的格式统一处理。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:23:27