使用镶木地板文件作为存储在 Hive 中创建外部表后获取 NULL

Posted

技术标签:

【中文标题】使用镶木地板文件作为存储在 Hive 中创建外部表后获取 NULL【英文标题】:Getting NULL after create external table in Hive using parquet file as storage 【发布时间】:2013-08-14 07:06:43 【问题描述】:

我正在使用 parquet 文件作为存储在 Hive 中创建外部表

hive> CREATE EXTERNAL TABLE test_data(
      c1 string, c2 int, c3 string, c4 string, c5 string, c6 float,
          c7 string, c8 string, c9 string, c10 string, c11 string, c12 string)
        ROW FORMAT SERDE 'parquet.hive.serde.ParquetHiveSerDe'
        STORED AS INPUTFORMAT 'parquet.hive.DeprecatedParquetInputFormat'
        OUTPUTFORMAT 'parquet.hive.DeprecatedParquetOutputFormat'
        LOCATION '/path/test_data/';

选择此表在任何行和列中都为 NULL

SELECT * FROM test_data;
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
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
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
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
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
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
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
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
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
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
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
NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
Time taken: 0.191 seconds, Fetched: 34 row(s)

我已经使用以下序列从制表符分隔文件中通过 Pig 转换得到 parquet 文件

grunt> A = LOAD '/path/test.data' USING PigStorage('\t')
        AS ( c1: chararray,c2: int,c3: chararray,
             c4: chararray,c5: chararray,c6: float,
             c7: chararray,c8: chararray,c9: chararray,
             c10: chararray, c11: chararray, c12: chararray );
grunt> STORE A INTO '/path/test_data' USING parquet.pig.ParquetStorer;

检查 parquet 文件是否包含有效数据,将其读回

grunt> B = LOAD'/path/test_data' USING parquet.pig.ParquetLoader;
grunt> DUMP B;
(19,14370,rs6054257,G,A,29.0,PASS,NS=3;DP=14;AF=0.5;DB;H2,GT:GQ:DP:HQ,0|0:48:1:51,51,1|0:48:8:51,51,1/1:43:5:.,.)
(20,17330,.,T,A,3.0,q10,NS=3;DP=11;AF=0.017,GT:GQ:DP:HQ,0|0:49:3:58,50,0|1:3:5:65,3,0/0:41:3)
(20,1110696,rs6040355,A,G,T,67.0,PASS,NS=2;DP=10;AF=0.333,0.667;AA=T;DB,GT:GQ:DP:HQ,1|2:21:6:23,27,2|1:2:0:18,2,2/2:35:4)
(20,1230237,.,T,.,47.0,PASS,NS=3;DP=13;AA=T,GT:GQ:DP:HQ,0|0:54:7:56,60,0|0:48:4:51,51,0/0:61:2)
(20,1234567,microsat1,GTC,G,GTCTC,50.0,PASS,NS=3;DP=9;AA=G,GT:GQ:DP,0/1:35:4,0/2:17:2,1/1:40:3)
(20,2234567,.,C,[13:123457[ACGC,50.0,PASS,SVTYPE=BND;NS=3;DP=9;AA=G,GT:GQ:DP,0/1:35:4,0/1:17:2,1/1:40:3)
(20,2234568,.,C,.TC,50.0,PASS,SVTYPE=BND;NS=3;DP=9;AA=G,GT:GQ:DP,0/1:35:4,0/1:17:2,1/1:40:3)
(20,2234569,.,C,CT.,50.0,PASS,SVTYPE=BND;NS=3;DP=9;AA=G,GT:GQ:DP,0/1:35:4,0/1:17:2,1/1:40:3)
(20,3234569,.,C,<INV>,50.0,PASS,SVTYPE=BND;NS=3;DP=9;AA=G,GT:GQ:DP,0/1:35:4,0/1:17:2,1/1:40:3)
(20,4234569,.,N,.[13:123457[,50.0,PASS,SVTYPE=BND;NS=3;DP=9;AA=G,GT:GQ:DP,0/1:35:4,0/1:17:2,./.:40:3)
(20,5234569,.,N,[13:123457[.,50.0,PASS,SVTYPE=BND;NS=3;DP=9;AA=G,GT:GQ:DP,0/1:35:4,0/1:17:2,1/1:40:3)
(Y,17330,.,T,A,3.0,q10,NS=3;DP=11;AF=0.017,GT:GL,0:0,49,0:0,3,1:41,0)

我做错了什么?

【问题讨论】:

将其发布到 hive 用户组 user@hive.apache.org 可能是更好的选择。 我遇到了同样的问题。但同样的查询在 Impala 中运行良好!!! 【参考方案1】:

在我的例子中,Hive 似乎对列名很敏感。

从 Spark 中的数据框中导出我的 parquet 文件后,我必须在 Hive 中使用与最初在 Spark 数据框中完全相同的列名。

当我使用诸如c1 之类的通用列名时,我会得到该特定列中所有值的NULL 值。

【讨论】:

【参考方案2】:

在我的例子中,HDFS 文件是逗号分隔格式,我没有在命令中定义行格式分隔。喜欢:

CREATE EXTERNAL TABLE TABLENAME(COL1 INT, COL2 STRING....) LOCATION '/user/....';

它用于创建具有相同行数但所有值都为空的表。我将上面的命令修改如下,它就像魅力一样:

CREATE EXTERNAL TABLE TABLENAME (COL1 INT, COL2 STRING....) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' LOCATION '/user/.....';

【讨论】:

【参考方案3】:

我也遇到过类似的问题。

此问题的主要原因是架构不匹配。首先检查您正在使用的镶木地板文件的架构。如果它是一个进程的输出,它有一个 _metadata 或相关的元数据文件。打开并查看名称和类型列。基于此模式创建表将有很大帮助! 还要检查压缩格式(Snappy、GZIP)并在TBLPROPERTIES ('PARQUET.COMPRESS'='GZIP') 中提供 当我不得不使用从 spark Dataframe 中持久保存的 Parquet 文件时,我遇到了类似的问题。列名与我创建的表不同,我得到了所有 NULL。

【讨论】:

【参考方案4】:

试试

创建外部表 test_data( c1 字符串,c2 整数,c3 字符串,c4 字符串,c5 字符串,c6 浮点数, c7 字符串、c8 字符串、c9 字符串、c10 字符串、c11 字符串、c12 字符串) 行格式 SERDE 'parquet.hive.serde.ParquetHiveSerDe' 具有SERDEPROPERTIES ("区分大小写"="c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12") 存储为 INPUTFORMAT 'parquet.hive.DeprecatedParquetInputFormat' OUTPUTFORMAT 'parquet.hive.DeprecatedParquetOutputFormat' 位置'/path/test_data/'

【讨论】:

以上是关于使用镶木地板文件作为存储在 Hive 中创建外部表后获取 NULL的主要内容,如果未能解决你的问题,请参考以下文章

将 avro 转换为镶木地板(也许使用 hive?)

即使存在与之关联的镶木地板文件,Hive 外部表也不显示任何数据

镶木地板上的配置单元外部表未获取数据

在 s3 pyspark 作业中创建单个镶木地板文件

如何在scala中创建镶木地板?

使用 pyspark 插入镶木地板文件时,Hive 表需要对每个新分区进行“修复”