【问题标题】:Dynamically create Hive external table with Avro schema on Parquet Data在 Parquet Data 上使用 Avro 模式动态创建 Hive 外部表
【发布时间】:2015-12-09 14:52:45
【问题描述】:

我正在尝试动态(未在 Hive DDL 中列出列名和类型)在 parquet 数据文件上创建 Hive 外部表。我有底层镶木地板文件的 Avro 模式。

我的尝试是在 DDL 下面使用:

CREATE EXTERNAL TABLE parquet_test
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.avro.AvroSerDe'
STORED AS PARQUET
LOCATION 'hdfs://myParquetFilesPath'
TBLPROPERTIES ('avro.schema.url'='http://myHost/myAvroSchema.avsc');

使用正确的架构成功创建了我的 Hive 表,但是当我尝试读取数据时:

SELECT * FROM parquet_test;

我收到以下错误:

java.io.IOException: org.apache.hadoop.hive.serde2.avro.AvroSerdeException: Expecting a AvroGenericRecordWritable

有没有办法成功创建和读取 Parquet 文件,而无需在 DDL 中提及列名和类型列表?

【问题讨论】:

  • 如果底层数据是 parquet 格式,我相信使用 avro schema 是无法读取的。更像是拿着英语词典看法语书。
  • 我只使用 AvroSerDe 进行架构推断...
  • 上述错误(期望 AvroGenericRecordWritable)表示您正在尝试使用 AvroSerde 读取 parquet 格式记录。 ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.avro.AvroSerDe' 告诉 hive 使用 AvroSerde 解码数据,但数据不是 avro 格式。
  • 是的,我正在尝试寻找替代解决方案,也许我应该从 Avro 模式生成 Hive 查询。但令我惊讶的是,没有更简单的解决方案。
  • 我没有测试过,但是试试这个 CREATE TABLE avro_test ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.avro.AvroSerDe' STORED AS AVRO TBLPROPERTIES ('avro.schema.url'= 'myHost/myAvroSchema.avsc');创建外部表 parquet_test LIKE avro_test 存储为 PARQUET LOCATION 'hdfs://myParquetFilesPath';

标签: hive avro parquet


【解决方案1】:

以下查询有效:

CREATE TABLE avro_test ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.avro.AvroSerDe' STORED AS AVRO TBLPROPERTIES ('avro.schema.url'='myHost/myAvroSchema.avsc'); 

CREATE EXTERNAL TABLE parquet_test LIKE avro_test STORED AS PARQUET LOCATION 'hdfs://myParquetFilesPath';

【讨论】:

  • 我正在运行 Hive 1.1.0,但这对我不起作用。我得到java.io.IOException: org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.ClassCastException: org.apache.hadoop.io.Text cannot be cast to org.apache.hadoop.io.IntWritable
  • 错误消息表明特定列在 parquet 文件中是文本格式,在您的 avro 模式中它被定义为 int。因此错误。将该特定列的 avro 模式更改为 String 并重试。
  • 我认为我的问题来自不同且不兼容的模式。现在工作正常。谢谢!
  • 另一种解决方案是创建我自己的 SerDe:我需要来自 AvroSerDe 的是来自 avro 模式的模式推断。因此,我必须创建一个扩展 org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe 的类,并使用 org.apache.hadoop.hive.serde2.avro.AvroSerde 对象覆盖方法 public boolean shouldStoreFieldsInMetastore(Map<String, String> tableParams)。这似乎很容易用 Hive 1.2.0 编写。
  • 我遇到了失败:ParseException 行 1:55 在 avro_test 附近的“STORED”处缺少 EOF。蜂巢版本-0.14。在 hive 1.2 上运行良好
猜你喜欢
  • 2016-03-16
  • 2020-02-21
  • 2019-11-09
  • 1970-01-01
  • 2014-12-09
  • 2015-07-22
  • 1970-01-01
  • 2018-09-06
相关资源
最近更新 更多