蜂巢。动态分区并插入特定列

Posted

技术标签:

【中文标题】蜂巢。动态分区并插入特定列【英文标题】:HIVE. Dynamic partitioning and Insert into specific column 【发布时间】:2016-11-21 10:44:50 【问题描述】:

有一个包含大约 100 列的 HIVE 表,按列 ClientNumber 和 Date 进行分区。 我正在尝试将另一个 HIVE 表中的数据插入到仅 30 列中,并动态创建 Date 分区。

问题是所有数据都加载到“ClientNumber=123/date=__HIVE_DEFAULT_PARTITION__”分区中,这并不完全是预期的。

脚本如下所示:

set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;

FROM DBName.Table2
INSERT INTO TABLE DBName.Table1
PARTITION(ClientNumber=123, `Date`)   
(col1, col2, ..., col29, `Date`) 
SELECT 
col1, col2, ..., col29, eventDate as `Date`

Date 查询检索到的值都是正确的,没有 NULL 或其他异常值。 删除或添加动态分区参数没有区别。 提供特定的Date 值(而不是动态查询填充的值)会导致创建正确的分区。

在分区表中填充特定数量的列时,我是否遗漏了什么技巧或一些问题?

附:是否值得考虑将导入脚本中的所有其他列 (col31 - col100) 列为 NULL?

【问题讨论】:

更新: 1. Date 列在创建表时被声明为分区字段。列的保留关键字或别名不是问题 - 在其他情况下也适用。 2. 使用'cast(NULL as string) as colN'定义列出所有剩余的列可以被认为是这种情况的解决方法。但是,脚本变得更大,我仍然想了解 INSERT 特定字段的问题。 【参考方案1】:

如果我的问题正确,则插入或选择中不应包含“日期”字段。如果您使用别名,它可能会破坏分区规则的要求。因为它期望定义模式的相同字段。脚本应该是...

FROM DBName.Table2
INSERT INTO TABLE DBName.Table1
PARTITION(ClientNumber=123, Date)   
SELECT col1, col2, ..., col29, eventDate as Date

【讨论】:

感谢您的建议。但是,Date 列用于决定应该使用哪个动态分区,并且还根据一些 unix 时间戳(我简单地将其标记为 eventDate)计算得出。所以Date 别名是必要的——并且在我为剩余字段提供 NULL 值的其他场景中工作。 @vasilik,更新的查询你可以试试这个 运行建议的查询返回:“SemanticException [错误 10044]:无法插入目标表,因为列号/类型不同‘日期’:表 insclause-0 有 100 列,但查询有 30 列。”我必须提供我要插入的特定字段的列表,否则它不会起作用。插入完整的字段列表可以正常工作,但这并不能解决问题。【参考方案2】:

是的,有一种更好的方法来提供许多列名。您可以使用 Hive 的“Regex Column Specification”:列名的正则表达式。您的查询将是:

    SET hive.support.quoted.identifiers=none;
    FROM DBName.Table2
    INSERT INTO TABLE DBName.Table1
    PARTITION(ClientNumber=123, Date)   
    SELECT `(eventDate)?+.+`, eventDate as Date;

这意味着“从 Table2 中选择除 eventDate 之外的所有名称”。

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Select#LanguageManualSelect-REGEXColumnSpecification

这对于某些用例来说仍然很笨拙,而我工作过的其他地方编写了脚本来从表模式自动生成 Hive 查询。

【讨论】:

【参考方案3】:

如果它对某人有用,值得阅读Corrupt rows written to __HIVE_DEFAULT_PARTITION__ when attempting to overwrite Hive partition中的答案

在我意识到分区列应该位于 DF 末尾是有限制的之前,我已经花了一些愚蠢的时间来解决同样的问题。就我而言,我只是更改了我的 DF 的 SQL 查询,将分区列选为最后一个。

【讨论】:

以上是关于蜂巢。动态分区并插入特定列的主要内容,如果未能解决你的问题,请参考以下文章

如何从具有动态分区的选择查询中插入 Hive 中的列?

Hive分区(静态分区+动态分区)

Hive动态分区与静态分区,数据插入,区别

Hive动态分区

使用Hive SQL插入动态分区的Parquet表OOM异常分析

使用Hive SQL插入动态分区的Parquet表OOM异常分析