十进制数据类型未在 Spark 和 Hive 中正确存储值



我在存储十进制数据类型时遇到问题,不确定是错误还是我做错了什么

文件中的数据如下所示

Column1 column2 column3
steve   100     100.23
ronald  500     20.369
maria   600     19.23

当我使用 csv 阅读器推断 Spark 中的模式时,它将 column3 的数据类型作为字符串,所以我将其转换为十进制并将其保存为表。

现在,当我访问该表时,它通过以下方式显示输出,消除小数

Column1 column2 column3
steve   100     100
ronald  500     20
maria   600     19

我还在 Hive 中测试了同样的事情,创建了一个将 column3 作为十进制的本地表,并用数据加载它,同样的事情它没有将它们存储为十进制。

在这方面的任何帮助将不胜感激。

这是上面的代码

在火花中 文件的架构

root
 |-- DEST_AIRPORT_ID: integer (nullable = true)
 |-- DEST_AIRPORT_SEQ_ID: integer (nullable = true)
 |-- DEST_CITY_MARKET_ID: integer (nullable = true)
 |-- DEST string: string (nullable = true)
 |-- DEST_CITY_NAME: string (nullable = true)
 |-- DEST_STATE_ABR: string (nullable = true)
 |-- DEST_STATE_FIPS: integer (nullable = true)
 |-- DEST_STATE_NM: string (nullable = true)
 |-- DEST_WAC: integer (nullable = true)
 |-- DEST_Miles: double (nullable = true)

法典

from pyspark import SparkContext
sc =SparkContext()
from pyspark.sql.types import *
from pyspark.sql import HiveContext
sqlContext = HiveContext(sc)
Data=sqlContext.read.format("com.databricks.spark.csv").options(header="true").options(delimiter=",").options(inferSchema="true").load("s3://testbucket/Data_test.csv")
Data1=Data.withColumnRenamed('DEST string','DEST_string')
Data2 =Data1.withColumn('DEST_Miles',Data1.DEST_Miles.cast('Decimal'))
Data2.saveAsTable('Testing_data', mode='overwrite',path='s3://bucketname/Testing_data')

转换为十进制后的架构

root
 |-- DEST_AIRPORT_ID: integer (nullable = true)
 |-- DEST_AIRPORT_SEQ_ID: integer (nullable = true)
 |-- DEST_CITY_MARKET_ID: integer (nullable = true)
 |-- DEST string: string (nullable = true)
 |-- DEST_CITY_NAME: string (nullable = true)
 |-- DEST_STATE_ABR: string (nullable = true)
 |-- DEST_STATE_FIPS: integer (nullable = true)
 |-- DEST_STATE_NM: string (nullable = true)
 |-- DEST_WAC: integer (nullable = true)
 |-- DEST_Miles: decimal (nullable = true)

对于蜂巢

create table Destination(
        DEST_AIRPORT_ID int,
        DEST_AIRPORT_SEQ_ID int,
        DEST_CITY_MARKET_ID int,
        DEST string,
        DEST_CITY_NAME string,
        DEST_STATE_ABR string,
        DEST_STATE_FIPS string,
        DEST_STATE_NM string,
        DEST_WAC int,
        DEST_Miles Decimal(10,0)
      );
INSERT INTO TEST_DATA SELECT * FROM TESTING_data;  

如果您还需要更多信息,请告诉我。

谢谢谢谢

Hive V0.12 中的DECIMAL表示"一个大的浮点"。就像 Oracle 中的 NUMBER(38) 一样。

但是在后来的版本中,有一个重大的变化,没有任何小数位数/精度规范的DECIMAL现在意味着"一个大整数"。就像甲骨文中的数字(10,0)一样。

参考

  • 蜂巢语言手册/数据类型
  • 一个冗长的PDF文档,在 cwiki.apache.org 某处标记为"Hive十进制精度/小数位数支持"

底线:你必须明确定义你想要多少位数,这正是几十年前ANSI SQL标准所期望的。例如,DECIMAL(15,3) 将在整数部分容纳 12 位数字 + 在小数部分容纳 3 位数字(即 15 位数字,任意位置带有逗号)。

Spark 和 Hive 的默认精度均为 10,十进制类型的小数位数均为零。这意味着如果不指定小数位数,小数点后将没有数字。

该文件具有不同的分隔符(我认为选项卡),并且您正在使用","读取文件。

是的,它会转换为字符串,但您不应该丢失数据。试试这个:

>>> lines = spark.read.options( delimiter='t', header='true').csv("/home/kiran/km/km_hadoop/data/data_tab_sep")
>>> lines.show()
+-------+-------+-------+
|Column1|column2|column3|
+-------+-------+-------+
|  steve|    100| 100.23|
| ronald|    500| 20.369|
|  maria|    600|  19.23|
+-------+-------+-------+
>>> lines.printSchema()
root
 |-- Column1: string (nullable = true)
 |-- column2: string (nullable = true)
 |-- column3: string (nullable = true)

您可以像下面这样转换为DoubleType。(注意:对于您的情况,您不需要它,因为您正在写信给 FS)

>>> from pyspark.sql.types import DoubleType
>>> lines.select(lines["column1"], lines["column2"], lines["column3"].cast(DoubleType())).printSchema()
root
 |-- column1: string (nullable = true)
 |-- column2: string (nullable = true)
 |-- column3: double (nullable = true)

我在从 oracle 读取数据时遇到了同样的问题,我可以通过强制转换来解决这个问题

joinedDF.col("START_EPOCH_TIME").cast("string") 

相关内容

  • 没有找到相关文章

最新更新