Улей: запись заголовков столбцов в локальный файл?
Документация улья снова отсутствует:
Я хотел бы записать результаты запроса в локальный файл, а также имена столбцов.
Hive поддерживает это?
Insert overwrite local directory 'tmp/blah.blah' select * from table_name;
Кроме того, отдельный вопрос: является ли Stackru лучшим местом для получения справки по Hive? @ Ниджа, была очень полезна, но я не хочу беспокоить их...
7 ответов
Hive поддерживает запись в локальный каталог. Ваш синтаксис выглядит правильным для этого.
Проверьте документы на SELECTS и FILTERS для получения дополнительной информации.
Я не думаю, что у Hive есть способ записать имена столбцов в файл для вашего запроса.,, Я не могу точно сказать, что это не так, но я не знаю пути.
Я думаю, что единственное место лучше, чем SO для вопросов Hive, это список рассылки.
Да, ты можешь. Положить set hive.cli.print.header=true;
в .hiverc
файл в вашем основном каталоге или любой другой файл свойств пользователя куста.
Неясное предупреждение: будьте осторожны, так как это приводило к сбою моих запросов в прошлом (но я не могу вспомнить причину).
Действительно, ответ @nija правильный - по крайней мере, насколько я знаю. Нет никакого способа написать имена столбцов при выполнении insert overwrite into [local] directory ...
(используете ли вы локальный или нет).
Что касается сбоев, описанных @user1735861, в кусте есть известная ошибка 0.7.1
(исправлено в 0.8.0
что после set hive.cli.print.header=true;
, вызывает NullPointerException
для любой команды / запроса HQL, которая не производит вывод. Например:
улей -S улей> использовать по умолчанию; hive> set hive.cli.print.header=true; улей> использовать по умолчанию; Исключение в потоке "main" java.lang.NullPointerException в org.apache.hadoop.hive.cli.CliDriver.processCmd(CliDriver.java:222) в 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(собственный метод) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) в java.lang.reflect.Method.invoke(Method.java:616) в org.apache.hadoop.util.RunJar.main(RunJar.java:197)
Тогда как это хорошо:
улей -S hive> set hive.cli.print.header=true; улей> выберите * из двойного; с с улей>
Хотя не-HQL-команды хороши (set
,dfs
!
, так далее...)
Более подробная информация здесь: https://issues.apache.org/jira/browse/HIVE-2334
Я столкнулся с этой проблемой сегодня и смог получить то, что мне нужно, выполнив 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
Это немного громоздко, но, по крайней мере, вы можете получить то, что вам нужно, с помощью одного запроса.
Надеюсь это поможет!
Не лучшее решение, но вот что я делаю:
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
Вот мой взгляд на это. Обратите внимание, я не очень хорошо разбираюсь в 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/*