如何使用 spark 在 Hive 中正确加载数据?

Posted

技术标签:

【中文标题】如何使用 spark 在 Hive 中正确加载数据?【英文标题】:How do I load data correctly in Hive using spark? 【发布时间】:2017-06-28 05:15:53 【问题描述】:

我想输入看起来像-

的数据
"58;""management"";""married"";""tertiary"";""no"";2143;""yes"";""no"";""unknown"";5;""may"";261;1;-1;0;""unknown"";""no"""
"44;""technician"";""single"";""secondary"";""no"";29;""yes"";""no"";""unknown"";5;""may"";151;1;-1;0;""unknown"";""no"""
"33;""entrepreneur"";""married"";""secondary"";""no"";2;""yes"";""yes"";""unknown"";5;""may"";76;1;-1;0;""unknown"";""no"""
"47;""blue-collar"";""married"";""unknown"";""no"";1506;""yes"";""no"";""unknown"";5;""may"";92;1;-1;0;""unknown"";""no"""

我的创建表语句是 as-

sqlContext.sql("create table dummy11(age int, job string, marital string, education string, default string, housing string, loan string, contact string, month string, day_of_week string, duration int, campaign int, pday int, previous int, poutcome string, emp_var_rate int, cons_price_idx int, cons_conf_idx int, euribor3m int, nr_employed int, y string)row format delimited fields terminated by ';'")

当我运行语句时-

sqlContext.sql("from dummy11 select age").show()

sqlContext.sql("from dummy11 select y").show()

它返回 NULL 值而不是正确的值,尽管其他值是可见的

那我该如何纠正呢?

【问题讨论】:

你是如何读取数据的? 当您考虑您的第一张唱片时;它有 17 个字段(将 ; 视为 delim),但在您的查询中,您定义了 21 个字段,对吗!! sqlContext.sql("load data inpath 'hdfs://user/nikita.jaiswal25_gmail/dataset.csv' into table dummy11") @RaktotpalBordoloi 是的,这是正确的......我如何正确阅读?我也必须声明这些字段,因为我的数据集很大。它只是我用来检查错误的虚拟 4 行。其余数据也可能有 21 个值。这种类型的输入在 Hive 中是否可行。 分隔符是必需的,即使这些记录没有任何值 - 在 hive 中。 ----->>> 因此,根据查询,前 17 个字段(来自您定义的 DDL)填充了值;其余部分填充为 NULL。 【参考方案1】:

由于您使用的是 Hive QL 语法,因此您需要在处理之前验证输入数据。

在您的数据中,很少有记录的列数少于 DDL 中定义的实际列数。

因此,对于这些记录,其余列(从最后一个)设置为 NULL;因为该行没有足够的值。

这就是为什么,最后一列 y 的值是 NULL

另外,在 DDL 中,第一个字段的数据类型是 INT;但在记录中,第一个字段值为:

"58
"44
"33

由于",这些值没有被类型转换为INT;将字段值设置为NULL

根据您提供的 DDL 和数据,值设置为:

age             "58
job             ""management""
marital         ""married""
education       ""tertiary""
default         ""no""
housing         2143
loan            ""yes""
contact         ""no""
month           ""unknown""
day_of_week     5
duration        ""may""
campaign        261
pday            1
previous        -1
poutcome        0
emp_var_rate    ""unknown""
cons_price_idx  ""no""
cons_price_idx  NULL
cons_conf_idx   NULL
euribor3m int   NULL
nr_employed     NULL
y               NULL

检查最后 5 列的 NULL 值。

因此,如果这不是预期的,您需要先验证数据,然后再继续。

对于age 列,如果需要INT 类型,请清理数据以删除不需要的" 字符。


解决方法

作为解决方法,您可以在开始时将age 定义为STRING,因为使用火花转换来解析第一个字段并将其转换为INT

import org.apache.spark.sql.functions._
val ageInINT = udf  (make: String) =>
  Integer.parseInt(make.substring(1))

df.withColumn("ageInINT", ageInINT(df("age"))).show

df 是您在执行 hive DDL 时创建的数据框,列 agesTRING

现在,您可以对新列 ageInINT 执行操作,而不是对具有 INTEGER 值的列 age 执行操作。

【讨论】:

【参考方案2】:

由于您的数据在年龄之前包含",因此它被视为字符串。在代码中,您已将其定义为 int,因此 sql 解析器正在尝试查找整数值,因此您将获得 null 记录。将age int 更改为age string,您将能够看到结果。

请参阅下面使用 Spark HiveContext 的工作示例。

import org.apache.spark.sql.hive.HiveContext;
import org.apache.spark.sql.types._
import org.apache.spark.SparkContext
import org.apache.spark.SparkConf

val sc = new SparkContext(conf)
val sqlContext = new HiveContext(sc)

sqlContext.sql("create external table dummy11(age string, job string, marital string, education string, default string, housing string, loan string, contact string, month string, day_of_week string, duration int, campaign int, pday int, previous int, poutcome string, emp_var_rate int, cons_price_idx int, cons_conf_idx int, euribor3m int, nr_employed int, y string)row format delimited fields terminated by ';' location '/user/skumar143/stack/'")
sqlContext.sql("select age, job from dummy11").show()

它的输出:

+---+----------------+
|age|             job|
+---+----------------+
|"58|  ""management""|
|"44|  ""technician""|
|"33|""entrepreneur""|
|"47| ""blue-collar""|
+---+----------------+

【讨论】:

在这里您已将age 声明为字符串。我需要在进一步计算中使用age。我不能将其保留为string,因为它不会被计算。我们需要将其设为int,以便它可以用于数学计算。 那么请使用不同的方法来解析数据。创建一个数据框和临时表来解析数据,然后将其加载到最终表中。其他解决方法是将此列转换为数字类型或删除所有想要的"

以上是关于如何使用 spark 在 Hive 中正确加载数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spark 将镶木地板文件加载到 Hive 表中?

查询Spark同时加载的hive表时如何避免错误

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

Spark SQL 在不配置 Hive 的情况下加载数据?

如何将数据写入 Hive 表?

加载或指向多个 parquet 路径以使用 hive 或 prestodb 进行数据分析