通过数据块将新分区添加到 Hive External Table

Add New Partition to Hive External Table via databricks

我有一个文件夹,该文件夹以前有基于 ingestiontime 的子文件夹,这也是其 Hive Table.

中使用的原始 PARTITION

所以文件夹看起来是 -

s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200712230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200711230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200710230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200709230000/....
........

在每个 ingestiontime 文件夹中,数据以 PARQUET 格式存在。

现在,在同一个 myStreamingData 文件夹中,我正在添加另一个包含类似数据但位于名为 businessname 的文件夹中的文件夹。

所以我的文件夹结构现在看起来像 -

s3://MyDevBucket/dev/myStreamingData/businessname=007/ingestiontime=20200712230000/....
s3://MyDevBucket/dev/myStreamingData/businessname=007/ingestiontime=20200711230000/....
s3://MyDevBucket/dev/myStreamingData/businessname=007/ingestiontime=20200710230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200712230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200711230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200710230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200709230000/....
    ........

所以我也需要将 businessname 分区中的数据添加到我当前的配置单元 table 中。

为了实现这一点,我 运行 ALTER 查询 - (在 Databricks 上)

%sql
alter table gp_hive_table add partition (businessname=007,ingestiontime=20200712230000) location "s3://MyDevBucket/dev/myStreamingData/businessname=007/ingestiontime=20200712230000"

但是我收到这个错误 -

Error in SQL statement: AnalysisException: businessname is not a valid partition column in table `default`.`gp_hive_table`.;

我哪里做错了?

提前致谢。

alter table gp_hive_table add partition是在已经定义好分区方案的table中添加分区(数据位置,不是新列),不改变当前分区方案,只是增加分区元数据,即在某些位置存在与某些分区列值对应的分区。

如果要更改分区列,需要重新创建table。:

  1. 删除(检查它是外部的)table:DROP TABLE gp_hive_table;

  2. 使用新的分区列创建 table。不会自动创建分区。

  3. 现在您可以使用ALTER TABLE ADD PARTITION添加分区或使用根据目录结构自动创建分区。在执行这些命令之前,目录结构应该已经匹配分区方案

所以, 根据@leftjoin 的建议,

而不是将没有 businessname 的配置单元 table 作为分区之一, 我所做的是 -

步骤 1 -> 使用 - PARTITION BY (businessname long,ingestiontime long)

创建配置单元 table

步骤 2 -> 执行查询 - MSCK REPAIR <Hive_Table_name> 自动添加分区。

步骤 3 -> 现在,存在不在文件夹 businessname 中的 ingestiontime 文件夹,即 像 -

这样的文件夹
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200712230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200711230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200710230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200709230000/....

我写了一小段代码来获取所有这样的分区,然后 运行 对所有这些分区进行以下查询 - ALTER TABLE <hive_table_name> ADD PARTITION (businessname=<some_value>,ingestiontime=<ingestion_time_partition_name>) LOCATION "<s3_location_of_all_partitions_not_belonging_to_a_specific_businesskey>

这解决了我的问题。

由于您已经在使用 Databricks 并且这是一个流式用例,因此您绝对应该认真考虑使用 Delta Lake tables。

您不必为显式...ADD PARTITION 和 MSCK 语句而烦恼。 具有 ACID 属性的 Delta Lake 将确保您的数据正确提交,如果您的工作失败,您将不会得到部分结果。一旦数据被提交,它就可供用户使用(同样没有 MSCK 和 ADD PARTITION)语句。

只需在您的 DDL 中将 'USING PARQUET' 更改为 'USING DELTA'。

您还可以(转换)您现有的 parquet table 到 Delta Lake table,然后开始使用 INSERT、UPDATE、DELETE、MERGE INTO、COPY INTO,来自 Spark 批处理和结构化流职位。优化将清理小文件问题。