Как установить переменные в скриптах HIVE
Я ищу SQL-эквивалент SET varname = value
в улье QL
Я знаю, что могу сделать что-то вроде этого:
SET CURRENT_DATE = '2012-09-16';
SELECT * FROM foo WHERE day >= @CURRENT_DATE
Но тогда я получаю эту ошибку:
символ '@' здесь не поддерживается
10 ответов
Вам нужно использовать специальный hiveconf для подстановки переменных. например
hive> set CURRENT_DATE='2012-09-16';
hive> select * from foo where day >= '${hiveconf:CURRENT_DATE}'
аналогично, вы можете передать в командной строке:
% hive -hiveconf CURRENT_DATE='2012-09-16' -f test.hql
Обратите внимание, что есть также env и системные переменные, так что вы можете ссылаться ${env:USER}
например.
Чтобы увидеть все доступные переменные, из командной строки запустите
% hive -e 'set;'
или из подсказки улья запустите
hive> set;
Обновление: я также начал использовать переменные hivevar, помещая их в фрагменты hql, которые я могу включить в CLI hive, используя source
команда (или передать опцию -i из командной строки). Преимущество здесь заключается в том, что переменная может затем использоваться с префиксом hivevar или без него и разрешать что-то похожее на глобальное или локальное использование.
Итак, предположим, что есть файл setup.hql, который устанавливает переменную tablename:
set hivevar:tablename=mytable;
тогда я могу привести в улей:
hive> source /path/to/setup.hql;
и использовать в запросе:
hive> select * from ${tablename}
или же
hive> select * from ${hivevar:tablename}
Я также мог бы установить "локальное" имя таблицы, которое будет влиять на использование ${tablename}, но не на ${hivevar:tablename}
hive> set tablename=newtable;
hive> select * from ${tablename} -- uses 'newtable'
против
hive> select * from ${hivevar:tablename} -- still uses the original 'mytable'
Вероятно, не слишком много значит для CLI, но может иметь hql в файле, который использует источник, но установить некоторые переменные "локально" для использования в остальной части сценария.
Большинство ответов здесь предложили либо использовать hiveconf
или же hivevar
Пространство имен для хранения переменной. И все эти ответы верны. Однако есть еще одно пространство имен.
Всего три namespaces
доступны для хранения переменных.
- hiveconf - куст начался с этого, вся конфигурация улья сохраняется как часть этого конф. Первоначально подстановка переменных не была частью улья, и когда она появилась, все переменные, определенные пользователем, также были сохранены как часть этого. Что, безусловно, не очень хорошая идея. Таким образом, было создано еще два пространства имен.
- hivevar: для хранения пользовательских переменных
- система: для хранения системных переменных.
И поэтому, если вы храните переменную как часть запроса (например, date или product_number), вы должны использовать hivevar
пространство имен, а не hiveconf
Пространство имен.
И вот как это работает.
hiveconf по-прежнему является пространством имен по умолчанию, поэтому, если вы не предоставите никакого пространства имен, он сохранит вашу переменную в пространстве имен hiveconf.
Однако когда дело доходит до ссылки на переменную, это не так. По умолчанию это относится к пространству имен hivevar. Смущает, верно? Это может стать понятнее со следующим примером.
Если вы не предоставляете пространство имен, как указано ниже, переменная var
будет храниться в hiveconf
Пространство имен.
set var="default_namespace";
Итак, для доступа к этому вам необходимо указать hiveconf
Пространство имен
select ${hiveconf:var};
И если вы не предоставите пространство имен, это выдаст вам ошибку, как указано ниже, причина в том, что по умолчанию, если вы пытаетесь получить доступ к переменной, она проверяет hivevar
только пространство имен. И в hivevar
нет переменной с именем var
select ${var};
Мы явно предоставили hivevar
Пространство имен
set hivevar:var="hivevar_namespace";
поскольку мы предоставляем пространство имен, это будет работать.
select ${hivevar:var};
И по умолчанию рабочее пространство, используемое при обращении к переменной hivevar
, следующее тоже будет работать.
select ${var};
Вы пытались использовать знак доллара и скобки, как это:
SELECT *
FROM foo
WHERE day >= '${CURRENT_DATE}';
На всякий случай кому-то нужно параметризовать запрос улья через cli.
Например:
hive_query.sql
SELECT * FROM foo WHERE day >= '${hivevar:CURRENT_DATE}'
Теперь выполните указанный выше sql файл из cli:
hive --hivevar CURRENT_DATE="2012-09-16" -f hive_query.sql
Два простых способа:
Использование улья конф
hive> set USER_NAME='FOO';
hive> select * from foobar where NAME = '${hiveconf:USER_NAME}';
Использование улья
На вашем CLI установите Vars, а затем используйте их в улье
set hivevar:USER_NAME='FOO';
hive> select * from foobar where NAME = '${USER_NAME}';
hive> select * from foobar where NAME = '${hivevar:USER_NAME}';
Документация: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+VariableSubstitution
Следует помнить, что нужно задавать строки, а затем обращаться к ним. Вы должны убедиться, что цитаты не сталкиваются.
set start_date = '2019-01-21';
select ${hiveconf:start_date};
Необходимо быть осторожным, устанавливая даты, а затем ссылаться на них в коде, так как строки могут конфликтовать. Это не будет работать с указанным выше параметром start_date.
'${hiveconf:start_date}'
При установке переменных с начальными и конечными кавычками. При обращении к ним в запросе мы должны помнить, что нельзя задавать одинарные или двойные кавычки для строк.
В Hive есть несколько вариантов установки переменных.
Если вы хотите установить переменную Hive из оболочки Hive, вы можете установить ее с помощью
hivevar
. Вы можете установить строковые или целочисленные типы данных. С ними проблем нет.
SET hivevar:which_date=20200808;
select ${which_date};
Если вы планируете установить переменные из сценария оболочки и хотите передать эти переменные в файл сценария Hive (HQL), вы можете использовать
--hivevar
опция при вызове команды hive или beeline.
# shell script will invoke script like this
beeline --hivevar tablename=testtable -f select.hql
-- select.hql file
select * from <dbname>.${tablename};
Вы можете экспортировать переменную в экспорте скрипта оболочки CURRENT_DATE="2012-09-16"
Тогда в hiveql вам нравится SELECT * FROM foo WHERE day >= '${env:CURRENT_DATE}'
Попробуйте этот метод:
set t=20;
select *
from myTable
where age > '${hiveconf:t}';
это хорошо работает на моей платформе.
Вы можете сохранить выходные данные другого запроса в переменной, а последний можно использовать в своем коде:
set var=select count(*) from My_table;
${hiveconf:var};