从 MySQL 到 Hive 的 Sqoop 导入成功,但选择返回所有 NULL 值

Posted

技术标签:

【中文标题】从 MySQL 到 Hive 的 Sqoop 导入成功,但选择返回所有 NULL 值【英文标题】:Sqoop import from MySQL to Hive is successful but select returns all NULL values 【发布时间】:2016-09-04 03:11:03 【问题描述】:

这已导入正确数量的记录,但我的 Hive 选择命令给了我 NULL 数据值。

hive> select * from widgets;
OK
NULL    NULL    NULL    NULL    NULL    NULL
NULL    NULL    NULL    NULL    NULL    NULL
NULL    NULL    NULL    NULL    NULL    NULL
NULL    NULL    NULL    NULL    NULL    NULL
NULL    NULL    NULL    NULL    NULL    NULL
NULL    NULL    NULL    NULL    NULL    NULL
Time taken: 0.179 seconds, Fetched: 6 row(s)

我正在使用以下命令将数据从 mysql 表导入 Hive 表:

sqoop import 
--connect jdbc:mysql://localhost/kmdb 
--table widgets  
-m 1 
--hive-import
--hive-table widgets

我的架构看起来不错,如下所示: hive> 描述小部件; 好的 id int 小部件名称字符串 价格翻倍 设计日期字符串 版本 int design_comment 字符串 耗时:0.268 秒,提取:6 行

我的数据看起来也不错,如下所示:

$ hdfs dfs -cat /user/hive/warehouse/widgets/part-m-00000_copy_1
1sprocket0.252010-02-101Connects two gizmos
2gizmo4.002009-11-304null
3gadget99.991983-08-1313Our flagship product

(注意:我可以在控制台上看到字段分隔符特殊字符,但由于某些渲染,它们没有显示在此处。)

背景:该表实际上是使用另一个 sqoop 命令创建的:

$sqoop create-hive-table 
   --connect jdbc:mysql://localhost/kmdb 
   --table widgets 
   --fields-terminated-by ','

这有什么不同吗?

有什么想法吗?

【问题讨论】:

在触发这个命令之前表widgets 是否存在? 是的,我使用另一个 sqoop 命令创建了表:>sqoop create-hive-table --connect jdbc:mysql://localhost/kmdb --table widgets --fields-terminated-by ' ,' 【参考方案1】:

您在/user/hive/warehouse/widgets 位置的数据是如何格式化的?是','分开的吗?您是否已经在 hive 中有表格小部件?您是否已经在 hive 中有表检查表定义中的字段分隔符是什么(使用描述格式化的小部件)

由于 sqoop 导入将导入数据和元数据(如果 hive 表不存在)。看起来您已经有一个带有除“^A”以外的字段分隔符的表。这就是为什么当您使用 sqoop 导入数据时,它会以“^A”作为字段分隔符加载数据。

您有 2 个选项来纠正它。

1) 删除表(删除表小部件),然后再次运行相同的 sqoop 命令,这将加载数据并使用默认字段分隔符 ^A 创建表。你会看到数据。

2) 不要删除表格并使用 hive 中的 describe 命令检查表格的字段分隔符(我假设分隔符是 , )。然后运行

sqoop import 
--connect jdbc:mysql://localhost/kmdb 
--table widgets  
-m 1 
--fields-terminated-by ','
--lines-terminated-by '/n'
--hive-import
--hive-overwrite

【讨论】:

嗨 Aditya,我看到的数据如下: [cloudera@quickstart ~]$ hdfs dfs -cat /user/hive/warehouse/widgets/part-m-00000 1sprocket0.252010-02-101Connects两个小玩意 2gizmo4.002009-11-304null 3gadget99.991983-08-1313我们的旗舰产品 但是我的 Hive 选择查询输出都是 NULL。该表是使用 sqoop 命令创建的。不知道这有什么不同。让我更新原始问题的更多细节:表创建和架构【参考方案2】:

我明白我在这里缺少什么。我们需要在创建表和数据导入时指定相同的分隔符。

-我创建了表格以使用字段分隔符',' - 我没有指定字段分隔符,所以 Hive 采用了默认分隔符。

在导入期间添加以下参数后它起作用了。

--fields-terminated-by ','

【讨论】:

【参考方案3】:

当我们使用给定的 import sqoop 命令时,由 self 创建的配置单元表和数据应该转储到给定的目录位置,如下所示。

> sqoop import --connect jdbc:mysql://xx.xx.xx.xx/tournament \
> --username "analytics" --password "xxxxxx" --table store_config \
> --target-dir maprfs:///user/hive/warehouse/tournament.db/store_config/  \
> --hive-import --create-hive-table --hive-table tournament.store_config

我们在这个导入命令中缺少什么?

> --fields-terminated-by

默认情况下,它将分隔符作为制表符,但如果要显式定义它,则需要使用此命令。

> --fields-terminated-by **char**

下次我们使用

覆盖数据时
> sqoop import --connect jdbc:mysql://xx.xx.xx.xx/tournament
> --username "xxxxxx" --password "xxxxxx" \
> --table store_config \
> --delete-target-dir --target-dir 'maprfs:///user/hive/warehouse/tournament.db/store_config/' \
> --lines-terminated-by '\n' -m 1

然后当我们通过 HIVE CLI 获取数据时,我们会遇到这个 NULL 问题。

hive> select * from store_config;
OK
NULL    NULL    NULL    NULL    NULL    NULL
NULL    NULL    NULL    NULL    NULL    NULL
NULL    NULL    NULL    NULL    NULL    NULL
NULL    NULL    NULL    NULL    NULL    NULL
NULL    NULL    NULL    NULL    NULL    NULL
NULL    NULL    NULL    NULL    NULL    NULL

那我该怎么办,很简单,我们只需在覆盖命令中添加 --fields-terminated-by "\001" 这个即可解决问题。

【讨论】:

【参考方案4】:

确保您在sqooping之前已经在hive中创建了表,并且所有列(HIVE TABLE)的顺序和数据类型必须与您的源表(MYSQL TABLE )。

【讨论】:

以上是关于从 MySQL 到 Hive 的 Sqoop 导入成功,但选择返回所有 NULL 值的主要内容,如果未能解决你的问题,请参考以下文章

使用sqoop从mysql导入数据到hive

Sqoop从本地MySQL导入到Hive为啥要求Sqoop一定要在HDFS中

如何使用 Sqoop 从 MySQL 增量导入到 Hive?

sqoop 导入从mysql导入数据到hive报类找不到

从 MySQL 到 Hive 的 Sqoop 导入成功,但选择返回所有 NULL 值

教程 | 使用Sqoop从MySQL导入数据到Hive和HBase