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

ufj5ltwl  于 2021-06-26  发布在  Hive
关注(0)|答案(4)|浏览(343)

我在使用decimal数据类型存储时遇到问题,不确定这是一个bug还是我做错了什么
文件中的数据如下所示

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

当我使用csv读取器推断spark中的模式时,它将column3的数据类型作为字符串,因此我将其转换为decimal并将其保存为table。
现在,当我访问这个表时,它以下面的方式显示输出,消除小数

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

我还在hive中测试了同样的事情,创建了一个列3为decimal的本地表,并将数据加载到该表中,同样的事情是不将它们存储为decimal。
在此方面的任何帮助都将不胜感激。
这是上面的代码
在文件的架构中

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)

为了Hive

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;

如果你还需要更多的信息,请告诉我。
谢谢,谢谢

v440hwme

v440hwme1#

文件有不同的分隔符(我认为是tab)&您正在用','读取文件。
是的,它会转换为字符串,但不应该丢失数据。试试这个:

>>> 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)
zwghvu4y

zwghvu4y2#

我在读取甲骨文的数据时也遇到了同样的问题,我可以用casting来解决这个问题

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

wi3ka0sx3#

DECIMAL 在hivev0.12中意味着“一个大浮点”。就像甲骨文中的数字(38)。
但在后来的版本中有一个重大的变化和变化 DECIMAL 没有任何规模/精度的规定,现在意味着“一个大整数”。就像甲骨文中的数字(10,0)。
参考
配置单元语言手册/数据类型
在cwiki.apache.org的某个地方有一个很长的pdf文档,标签是“hive decimal precision/scale support”
一句话:您必须显式地定义需要多少位,这正是几十年前ansisql标准所期望的。例如, DECIMAL(15,3) 将容纳整数部分的12位+小数部分的3位(即15位,任意位置带有逗号)。

nkhmeac6

nkhmeac64#

spark和hive的默认精度为10,小数类型的小数位数为0。也就是说,如果不指定比例,小数点后就没有数字了。

相关问题