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

PySpark读取Oracle NUMBER类型数据时保留整数格式的问题

解决PySpark读取Oracle NUMBER列时保留整数格式的问题

你的问题是Oracle表中NUMBER(38,10)和NUMBER(9)列实际存储的是整数,但PySpark通过JDBC读取后显示带 trailing zeros(比如100522.0000000000),想要输出纯整数格式,这里有几种实用方案:

方案1:在读取SQL中直接转换类型

修改dbtable里的查询语句,用CAST把列转成无小数位的数值类型,让Spark读进来就是整数类型:

source_df = self.spark.read.format("jdbc")\
    .option("url", self.Oracle_jdbc_url)\
    .option("dbtable", "(select CAST(C1 AS NUMBER(38)) C1, CAST(C2 AS NUMBER(9)) C2 from schema.table where rownum <=2 ) ")\
    .option("user", self.Oracle_Username)\
    .option("password", self.Oracle_Password)\
    .option("numPartitions",2)\
    .option("lowerBound", 1)\
    .option("upperBound",100000)\
    .option("partitionColumn", "c1")\
    .load()

source_df.show()

这种方式从数据源层面修正类型,后续处理无需再调整。

方案2:读取后转换列类型

如果不想修改查询SQL,读入DataFrame后再把列转成整数类型。注意NUMBER(38,10)的范围可能超过IntegerType上限,建议用LongType或BigInt避免溢出:

from pyspark.sql.types import LongType, IntegerType

source_df = self.spark.read.format("jdbc")\
    .option("url", self.Oracle_jdbc_url)\
    .option("dbtable", "(select C1,C2 from schema.table where rownum <=2 ) ")\
    .option("user", self.Oracle_Username)\
    .option("password", self.Oracle_Password)\
    .option("numPartitions",2)\
    .option("lowerBound", 1)\
    .option("upperBound",100000)\
    .option("partitionColumn", "c1")\
    .load()

# 转换列类型
source_df = source_df\
    .withColumn("C1", source_df["C1"].cast(LongType()))\
    .withColumn("C2", source_df["C2"].cast(IntegerType()))

source_df.show()

方案3:指定自定义Schema读取

通过customSchema选项直接告诉JDBC要读取的列类型,跳过默认的类型映射:

source_df = self.spark.read.format("jdbc")\
    .option("url", self.Oracle_jdbc_url)\
    .option("dbtable", "(select C1,C2 from schema.table where rownum <=2 ) ")\
    .option("user", self.Oracle_Username)\
    .option("password", self.Oracle_Password)\
    .option("numPartitions",2)\
    .option("lowerBound", 1)\
    .option("upperBound",100000)\
    .option("partitionColumn", "c1")\
    .option("customSchema", "C1 BIGINT, C2 INT")\
    .load()

source_df.show()

这个方案适合提前明确列类型和范围的场景,配置一次就能直接得到目标类型的DataFrame。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:52:26