Як встановити змінні в HIVE-скриптах


102

Я шукаю еквівалент SQL SET varname = valueв Hive QL

Я знаю, що можу зробити щось подібне:

SET CURRENT_DATE = '2012-09-16';
SELECT * FROM foo WHERE day >= @CURRENT_DATE

Але тоді я отримую цю помилку:

символ "@" не підтримується тут


На жаль, не існує безпечного способу встановлення змінної рядка, оскільки якщо хтось виконує запит без встановлення змінної, то рядок просто використовуватиме виклик змінної як рядок. :(
комбінаторист

Відповіді:


201

Для змінної заміни потрібно використовувати спеціальний 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 та system , тому ви можете посилатися ${env:USER}на приклад.

Щоб побачити всі доступні змінні, у командному рядку запустіть

% hive -e 'set;'

або із запиту на вулик, біжіть

hive> set;

Оновлення: я також почав використовувати змінні hivevar , вводячи їх у фрагменти hql, які я можу включити з CLI вулика за допомогою sourceкоманди (або передати як -i варіант з командного рядка). Перевага тут полягає в тому, що змінна може бути використана з префіксом hivevar або без нього, і дозволити щось подібне до глобального проти локального використання.

Отже, припустимо, є деякий setup.hql, який встановлює змінну імені таблиці:

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 у файлі, що використовує джерело , але встановити деякі змінні, "локально" для використання в решті сценарію.


1
Це передавання параметра з командного рядка, я розробляю запити в Кармасфері, і мені потрібно встановити кілька контактів у просьбі, щоб у моєму сценарії 10 разів не вводити коди. Чи можливо щось подібне?
user1678312

працює в обох напрямках, якщо ви можете, set CURRENT_DATE='2012-09-16';ви можете звернутися до цього пізніше з${hiveconf:CURRENT_DATE}
libjack

1
Як це працює, якщо у мене одночасно працює кілька завдань Hive? Чи в кінцевому підсумку вони збирають значення один у одного? Для автоматизації я будую файл HQL, попередньо додаючи його до деяких операторів SET. Я хочу переконатися, що якщо я надсилаю одночасно два завдання, які використовують однакові імена змінних, одне завдання не набере значення з іншого завдання. Семантика тут не зрозуміла з вашої відповіді.
MattD

5
це працює для мене на сервері Hive. Однак я налаштував деякі інтеграційні тести на локальній машині в IntelliJ. Я намагаюся таким чином використовувати змінну таким чином:FAILED: ParseException line x:y cannot recognize input near '$' '{' 'hiveconf' in expression specification
chepukha

1
@DatabaseCoder Наскільки мені відомо, нічого подібного не буде працювати. Всякий раз , коли мені потрібно що - щось на зразок того, що я повинен зробити перший запит , а потім перейти в «через --hiveconf»
libjack

21

Більшість відповідей тут пропонують використовувати hiveconfабо hivevarпростір імен для зберігання змінної. І всі ці відповіді вірні. Однак є ще один простір імен.

Є три namespacesдоступних для зберігання змінних.

  1. hiveconf - вулик, розпочатий з цього, вся конфігурація вулика зберігається як частина цієї конф. Спочатку заміна змінної не була частиною вулика, і коли вона була введена, всі визначені користувачем змінні зберігалися також як частина цього. Що, безумовно, не є хорошою ідеєю. Так було створено ще два простору імен.
  2. hivevar : для зберігання змінних користувачів
  3. система : для зберігання системних змінних.

Отже, якщо ви зберігаєте змінну як частину запиту (наприклад, дата або номер_файла), ви повинні використовувати 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};


3

Два простих способи:

Використання вулика конф

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


2

Одне, на що слід пам’ятати, - це встановлення рядків, а потім посилання на них. Ви повинні переконатися, що котирування не стикаються.

 set start_date = '2019-01-21';
 select ${hiveconf:start_date}; 

Встановлюючи дати, тоді посилаючись на них у коді, оскільки рядки можуть суперечити. Це не буде працювати з набором start_date вище.

 '${hiveconf:start_date}'

Ми маємо пам’ятати про те, щоб не задавати двічі одиничних чи подвійних лапок для рядків при посиланні на них у запиті.


2

На всякий випадок, коли комусь потрібно параметризувати запит вулика через 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

0

Спробуйте цей метод:

set t=20;
select *
from myTable
where age > '${hiveconf:t}'; 

він добре працює на моїй платформі.


0

Ви можете експортувати змінну в сценарій оболонки експорту CURRENT_DATE = "2012-09-16"

Тоді у hiveql вам подобається SELECT * FOO foo WHERE day> = '$ {env: CURRENT_DATE}'


-7

Ви можете зберігати результат іншого запиту в змінній, а останній ви можете використовувати той самий у своєму коді:

set var=select count(*) from My_table;
${hiveconf:var};

Ви помиляєтеся, виберіть count (*) з My_table; буде зберігатися у var .
Ілля Бистров
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.