添加decimal(16,8)列后Spark读取Hive表报错的解决方法咨询
解决方案
1. 避免使用select *,显式指定需要的列
问题根源在于select *会让Spark尝试解析表中所有列的元数据,哪怕你的Case Class里没用到那个有问题的decimal列。直接把查询改成只选择需要的列即可:
val query = """select otherColumn from my_table where ...""" spark.sql(query).as[MyTable]
2. 调整Spark的decimal兼容配置
在Spark会话初始化时添加以下配置,强制Spark兼容Hive的decimal存储格式:
val spark = SparkSession.builder() .appName("YourApp") .config("spark.sql.parquet.decimalCompatibility.enabled", "true") // 开启decimal兼容性 .config("spark.sql.parquet.enableVectorizedReader", "false") // 禁用向量化读取,避免类型解析冲突 .enableHiveSupport() .getOrCreate()
如果还是有问题,可以再加一个配置:
.config("spark.sql.decimalOperations.allowPrecisionLoss", "true")
3. 手动指定读取Schema,忽略目标列
如果必须使用select *,可以自定义Schema只包含你需要的字段,Spark会自动忽略Schema中未定义的列:
import org.apache.spark.sql.types._ val customSchema = StructType(Seq( StructField("otherColumn", StringType, nullable = true) )) spark.read.schema(customSchema) .table("my_table") .where("...") .as[MyTable]
4. 统一Hive表的decimal列精度
如果业务允许,可以把新增的decimal(16,8)列修改为和原有列一致的decimal(38,18),消除类型存储差异:
ALTER TABLE my_table CHANGE COLUMN yyy yyy DECIMAL(38,18);
内容的提问来源于stack exchange,提问作者Gaël J
相关产品推荐
相关产品推荐

