web-dev-qa-db-ja.com

ハイブ:列ヘッダーをローカルファイルに書き込む?

再び欠けているHiveドキュメント:

クエリの結果と列の名前をローカルファイルに書き込みたいです。

Hiveはこれをサポートしていますか?

Insert overwrite local directory 'tmp/blah.blah' select * from table_name;

また、別の質問:StackOverflowはHiveヘルプを取得するのに最適な場所ですか? @Nija、非常に役に立ちましたが、私はそれらを悩ませ続けることはありません...

28
CMaury

Hiveは、ローカルディレクトリへの書き込みをサポートします。あなたの構文も同様に適切に見えます。
チェックアウト SELECTSおよびFILTERSのドキュメント 追加情報が必要です。

Hiveには、実行しているクエリの列名をファイルに書き込む方法はないと思います。 。 。確かにそうではないと言うことはできませんが、方法はわかりません。

SOよりも良い場所は、 メーリングリスト のみです。

6
QuinnG

試してみる

set Hive.cli.print.header=true;
64
iggy

はい、できます。置く set Hive.cli.print.header=true;.hivercファイルをメインディレクトリまたは他のHiveユーザープロパティファイルに保存します。

あいまいな警告:これは過去に私のクエリをクラッシュさせたので注意してください(しかし、その理由は思い出せません)。

15
Dan B

実際、@ nijaの答えは正しいです-少なくとも私の知る限り。 insert overwrite into [local] directory ...を実行するときに(ローカルを使用するかどうかに関係なく)列名を記述する方法はありません。

@ user1735861で説明されているクラッシュに関して、Hive 0.7.10.8.0で修正済み)には既知のバグがあり、set Hive.cli.print.header=true;を実行した後にNullPointerException出力を生成しないHQLコマンド/クエリ。例えば:

 $ Hive -S 
 Hive>デフォルトを使用。 
 Hive> set Hive.cli.print.header = true; 
 Hive> use default; 
でスレッド「メイン」の例外Java.lang.NullPointerException 
 org.Apache.hadoop.Hive.cli.CliDriver.processCmd(CliDriver.Java:222)
 at org.Apache.hadoop.Hive.cli.CliDriver.processLine(CliDriver.Java:287)
 org.Apache.hadoop.Hive.cli.CliDriver.main(CliDriver.Java:517)
 at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at Sun.reflect.NativeMethodAccessorImpl .invoke(NativeMethodAccessorImpl.Java:57)
 at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
 at Java.lang.reflect.Method.invoke(Method.Java:616 )
 at org.Apache.hadoop.util.RunJar.main(RunJar.Java:197)

これは問題ありませんが、

 $ Hive -S 
 Hive> set Hive.cli.print.header = true; 
 Hive> select * from dual; 
 c 
 c 
ハイブ> 

ただし、非HQLコマンドは問題ありません(setdfs!など)

詳細はこちら: https://issues.Apache.org/jira/browse/Hive-2334

9
Hercynium

今日、この問題に遭遇し、元のクエリとヘッダー行を作成する新しいダミークエリの間でUNION ALLを実行することで、必要なものを得ることができました。各セクションに並べ替え列を追加し、ヘッダーを0に設定し、データを1に設定して、そのフィールドで並べ替え、ヘッダー行が先頭に表示されるようにしました。

create table new_table as
select 
  field1,
  field2,
  field3
from
(
  select
    0 as sort_col,  --header row gets lowest number
    'field1_name' as field1,
    'field2_name' as field2,
    'field3_name' as field3
  from
    some_small_table  --table needs at least 1 row
  limit 1  --only need 1 header row
  union all
  select
    1 as sort_col,  --original query goes here
    field1,
    field2,
    field3
  from
    main_table
) a
order by 
  sort_col  --make sure header row is first

少しかさばりますが、少なくとも1つのクエリで必要なものを取得できます。

お役に立てれば!

4
McLeodComputing

素晴らしい解決策ではありませんが、ここに私がやっていることがあります:

create table test_dat
ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t" STORED AS 
INPUTFORMAT "com.hadoop.mapred.DeprecatedLzoTextInputFormat" 
OUTPUTFORMAT "org.Apache.hadoop.Hive.ql.io.HiveIgnoreKeyTextOutputFormat" 
LOCATION '/tmp/test_dat' as select * from YOUR_TABLE;

Hive -e 'set Hive.cli.print.header=true;select * from YOUR_TABLE limit 0' > /tmp/test_dat/header.txt

cat header.txt 000* > all.dat
3
Jeremy

これが私の見解です。注意してください、私はbashにあまり詳しくないので、改善提案を歓迎します:)

#!/usr/bin/env bash

# works like this:
# ./get_data.sh database.table > data.csv

INPUT=$1
TABLE=${INPUT##*.}
DB=${INPUT%.*}

HEADER=`Hive -e "
  set Hive.cli.print.header=true;
  use $DB;
  INSERT OVERWRITE LOCAL DIRECTORY '$TABLE'
  row format delimited
  fields terminated  by ','
  SELECT * FROM $TABLE;"`

HEADER_WITHOUT_TABLE_NAME=${HEADER//$TABLE./}
echo ${HEADER_WITHOUT_TABLE_NAME//[[:space:]]/,}
cat $TABLE/*
2
tdgs