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

时间:2016-02-04 19:01:16

标签: apache-spark hive apache-spark-sql spark-csv

我在使用十进制数据类型存储时遇到问题,并且不确定它是否是错误或我做错了什么

文件中的数据如下所示

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作为十进制并加载了数据,并且同样的东西也没有将它们存储为十进制。

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

以下是上述代码

的代码

在spark中文件的架构

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;  

如果您仍需要更多信息,请与我们联系。

由于 感谢

4 个答案:

答案 0 :(得分:2)

Hive V0.12中的

DECIMAL意味着“一个大浮点”。就像Oracle中的NUMBER(38)一样。

但是在后来的版本中发生了重大变化,DECIMAL 没有任何规模/精度指定现在意味着“一个大整数”。就像Oracle中的NUMBER(10,0)一样。

参考

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

答案 1 :(得分:1)

Spark和Hive的默认精度均为10,Decimal类型的默认精度为零。这意味着如果您没有指定比例,小数点后面将没有数字。

答案 2 :(得分:0)

该文件有不同的分隔符(我认为标签)&您正在使用','。

读取文件

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

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

答案 3 :(得分:0)

从oracle读取数据时遇到了同样的问题,我可以通过强制修复来解决此问题

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