【问题标题】:Hive: Conditionally truncate and load the tableHive:有条件地截断并加载表
【发布时间】:2018-05-31 14:41:27
【问题描述】:

我正在尝试解决如果所有类别的源表在目标中都可用,则截断并加载目标表,否则不执行任何操作的问题。

我没有找到任何仅使用 hive 的解决方案,最终也使用 Shell 脚本 来解决此问题。

可以避免shell脚本吗?

目前的方法:

create_ind_table.hql

create temporary table temp.master_source_join
as select case when source.program_type_cd=master.program_type_cd then 1 else 0 end as IND
from source left join master
    on source.program_type_cd=master.program_type_cd;

--if all the categoies from source persent in master then will contain 1 else 0'
drop table if exists temp.indicator;
create table temp.indicator
as select min(ind)*max(ind) as ind from master_source_join;

如果所有源表类别都存在于主表中,以下是我调用的用于截断并加载主表的脚本。

tuncate_load_master.sh

beeline_cmd="beeline -u 'jdbc:hive2://abc.com:2181,abc1.com:2181,abc2.com:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2' --showHeader=flase --silent=true"
${beeline_cmd} -f create_ind_table.hql
## if indicator is 1 all the source category is present in master else not.

a=`${beeline_cmd} -e "select ind from temp.indicator;"`
temp=`echo $a | sed -e 's/-//g' | sed -e 's/+//g' | sed -e 's/|//g'`
echo $temp
if [ ${temp} -eq 1 ]
then
    echo "truncate and load the traget table"
    ${beeline_cmd} -e "insert overwrite table temp.master select * from temp.source;"
else
    echo "nothing to load"
fi

【问题讨论】:

    标签: hadoop hive hiveql


    【解决方案1】:

    使用动态分区的查询将仅覆盖源数据集中存在的分区。向您的表添加一个虚拟分区,如以下答案:https://stackoverflow.com/a/47505850/2700344

    您可以在同一子查询中使用解析min() 计算您的标志并按它进行过滤。

    计算的IND对于返回的所有行都是相同的。并且看起来解析 min() 就足够了,不需要计算 max()。按 IND=1 过滤。如果min() over()=0,它将不返回任何行并且不会覆盖表。

    --enable dynamic partitioning
    set hive.exec.dynamic.partition=true;
    set hive.exec.dynamic.partition.mode=nonstrict;
    
    insert overwrite table temp.master PARTITION(dummy_part) 
    select s.col1, s.col2, --list all columns here you need to insert 
            'dummy_value' as dummy_part --dummy partition column 
    from 
    (
    select s.*, 
          min(case when s.program_type_cd=m.program_type_cd then 1 else 0 end ) over() as IND
    from source s left join master m
        on s.program_type_cd=m.program_type_cd
    )s where ind=1 --filter will not return rows if min=0
    

    【讨论】:

    • 如果 select 不返回任何行,则插入覆盖实际上会截断表。这就是我使用 shell 脚本的原因。
    • @GaurangShah 是的,忘记了这个功能。请参阅我更新的答案。建议添加虚拟分区并使用动态分区。它将向数据位置添加一个目录级别,其他一切都保持不变。
    • 能否请您告诉我,如果我不使用分区,为什么插入覆盖并截断表,但如果我使用分区则不会。
    • @GaurangShah 如果您静态指定分区,它可能会覆盖,我不确定。但是如果从数据集中选择的分区并且数据集没有返回它,它怎么知道要重写哪个分区。它只覆盖数据集中的分区,而不是表中存在的所有分区。也许正确而简短的答案是“按设计”
    猜你喜欢
    • 2011-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-24
    • 1970-01-01
    • 2017-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多