0

我在 Spark 下创建了 ORC 格式的数据,如下所示:

var select: String = "SELECT ..."
sqlContext.sql(select).write.format("orc").save("/tmp/out/20160101")
select = "SELECT ..."
sqlContext.sql(select).write.format("orc").save("/tmp/out/20160102")
& so on...

现在我正在尝试在 Hive 中创建一个外部表,如下所示:

CREATE EXTERNAL TABLE `mydb.mytable`
 (`col1` string, 
  `col2` decimal(38,0), 
  `create_date` timestamp, 
  `update_date` timestamp)
  PARTITIONED BY (`my_date` string)
  STORED AS ORC
  LOCATION '/tmp/out/';

当我做:

"select count(*) from mydb.mytable"

我得到计数​​值为 0。但是在 Spark-shell 下,当我运行时:

val results = sqlContext.read.format("orc").load("/tmp/out/*/part*")
results.registerTempTable("results")
sqlContext.sql("select count(*) from results").show

我按预期得到了 500,000 行。

似乎“分区”没有被识别或其他东西。如何在 Spark 中创建的数据之上创建“外部”Hive 表?

4

1 回答 1

2

Hive 不会自动查找新分区。创建新分区后,您需要更新配置单元表。一个分区被创建并添加到 hive 表中,您可以根据需要在该分区中添加和删除文件,这些更改将立即反映,而无需更新元存储。

您可以使用ALTER TABLE查询在元存储中创建新分区。

ALTER TABLE mydb.mytable 
ADD PARTITION (my_date='20160101')
LOCATION '/tmp/out/20160101'

您将需要对每个输出目录执行此查询,以便 Hive 将它们拾取。

但是,Hive 对其分区有一个标准的命名约定<column_name>=<value>。使用这种命名方案有几个优点。首先,您可以从查询中省略该LOCATION子句ALTER TABLE,但它也允许您改为使用不同的查询:MSCK REPAIR TABLE <table_name>它将所有目录作为分区添加到元存储中。如果您想一次添加多个分区,这很有用,这意味着您不需要知道要添加的所有分区列的值。

于 2016-12-08T21:44:22.837 回答