将列名传递给 Hadoop Hive 流式作业

 2022-02-13 

Pass column names to Hadoop Hive streaming job

我正在 Hive 中编写一个 Hadoop 流式作业,我希望我的流式脚本能够了解它正在接收的表的列名。我尝试设置 set hive.cli.print.header=true; 但这会将名称打印到控制台而不使它们可用于脚本(据我所知)。

理想情况下,我还可以使数据类型也可用。

Hadoop Streaming API 或 Hive 中是否有允许我捕获流作业中的列名的选项?

更新:我能够从我的 Hive 脚本中提取 Hadoop 环境变量以及设置任意变量,并让它们在我的流脚本中可用。我正在调查对这些环境变量的访问是否允许我访问数据列名称或以一种骇人听闻的方式传递它们。


我正在提交一个答案,但这只有在"初始"数据包含列名时才有效,即。数据应该具有某种键值对结构。您现在可以将带有映射结构的输入类型存储在配置单元中并基于键进行查询。我给你举个例子。

假设您在 hdfs 中的"/user/input"位置有一个文件,其数据如下

1
2
A B C1=D1:C2=D2:C3=D3:C7=D4
E F C1=H1:C7=H2:C5=H4

在 hive 中执行以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
hive>> create external table my_external_table
       (column1 string, column2 string, my_map map<string,string>)
       row format delimited
       fields terminated by ' '
       collection items terminated by ':'
       map keys terminated by '='
       lines terminated by '\
'
       stored as textfile location '/user/input';
hive>> select * from my_external_table;
result>> A B {"C1":"D1","C2":"D2","C3":"D3","C7":"D4"}
         E F {"C1":"H1","C7":"H2","C5":"H4"}

现在你可以像这样执行查询了

1
2
3
4
5
6
7
8
9
10
11
hive >> select map_keys[my_map] from my_external_table;
result >> ["C1","C2","C3","C7"]
hive >> select map_values[my_map] from my_external_table;
result >> ["D1","D2","D3","D4"]
          ["H1","H2","H3","H4"]
hive >> select"C1",my_map['C1'] from my_external_table;
result >> C1    D1
          C1    H1
hive >> select map("C1",my_map['C1']) from my_external_table;
result >> {"C1":"D1"}
          {"C1":"H1"}

假设您想使用一些现有的地图键值创建一个新表,请执行以下操作:

1
2
3
4
hive >> create table my_new_table as select map('C1',my_map['C1'],'C2',my_map['C2']) from my_external_table;
hive >> select * from my_new_table;
result >> {"C1":"D1","C2":"D2"}
          {"C1":"H1","C2":null}

因此,使用上述方法,我可以创建新表来存储键名和值名,并对它们执行任何类型的转换,前提是初始数据存储为键值对。

注意:

  • 您可以轻松创建一个脚本,该脚本将根据需要将列名添加到您的配置单元查询中。
  • 假设您的"初始"数据不包含列名,您可以将数据转换为包含列名。或者,您可以使用自定义映射器将数据作为键值对回显
  • 我保留了自己的分隔符,可以根据需要随意更改。
  • 您也不需要 column1 和 column2 。我只是保留它是为了向您展示所有数据不必是键值对