我有一个配置单元外部表,该表在源系统上进行了分区,这意味着数据将来自多个源系统。 数据目录的结构为:
/app/hadoop/MyProject/SchemaName/TableName/PartitionColumn=SoruceSystem1
/app/hadoop/MyProject/SchemaName/TableName/PartitionColumn=SoruceSystem2
/app/hadoop/MyProject/SchemaName/TableName/PartitionColumn=SoruceSystem3
...
/app/hadoop/MyProject/SchemaName/TableName/PartitionColumn=SoruceSystemN
并且SourceSystem文件夹中的所有数据都是流数据,因此我们在每个源系统下都有很多文件:)。
我正在考虑每天一次合并所有这些文件,例如: SourceSystem1 中的所有文件将被合并,并且合并的文件将保留在 SoruceSystem1 文件夹中等等。
通常:
alter table schema.table PARTITION(PartitionColumn={SourceSystemName}) CONCATENATE;
在只有一个文件夹的情况下效果很好,但是我需要一次性处理所有文件夹。
解决方法是编写一个 shell脚本,以遍历所有分区,然后对每个源系统名称重复此语句,但是我正在寻找一些现成的方法来解决此问题用例。
非常感谢您的帮助。
答案 0 :(得分:1)
所以我们需要分两个步骤进行。
首先,我们在有问题的表中获取分区,并将其写入一个文本文件中,以备后用。
beeline --showHeader=false --outputformat=tsv2 --silent=true -e "show partitions database.table" > found_partitions.txt
这将写入找到的分区列表,但不包含标题或框架。
接下来,我们需要遍历分区列表,用逗号交换潜在的分区分隔符(part1=some/part2=thing
),因为前者不是合法的Hive字符。如果表中只有一个分区结构,则不会执行任何操作。我们还假设您所有分区都是字符串,并且需要用引号引起来。
#!/bin/bash
for line in `cat found_partitions.txt`; do
echo "the next partition is $line"
partition=`(echo $line | sed -e 's/\//,/g' -e "s/=/='/g" -e "s/,/',/g")`\'
beeline -e "alter table database.table partition($partition) concatenate"
done
注意:您可能必须设置一些配置,以便beeline为您工作。可能想为此设置别名。
beeline -u "jdbc:hive2://<SERVER>:<PORT>/;serviceDiscoveryMode=<zooKeeper>;zooKeeperNamespace=<hiveserver2>;principal=<USER>;transportMode=<SOMETHING>;httpPath=<SOMETHING>"