Невозможно определить динамический параметр в запросе на куст

Я пытаюсь настроить некоторые представления в Hive, которые будут принимать дату в качестве динамического параметра. В моей работе ниже я поменял местами переменную hiveconf в предложении Select, чтобы мы могли видеть, что происходит, но принцип остался прежним

В соответствии с этим и этим я должен иметь возможность включить оператор в "$ {hiveconf: dateRangeFrom}" в свой оператор Create View, предоставив переменную hiveconf: dateRangeFrom во время выполнения для максимального счастья, но этого просто не происходит - похоже, что Hive использует любое значение, назначенное переменной при создании View, и жестко кодирует его в определении View, а не подставляет его во время выполнения, как вы могли бы ожидать.

У меня есть обходной путь, при котором я предоставляю параметр в файл sql, который затем создает все представления, подставляя в него желаемое значение, но это не является устойчивым

Все рабочие ниже, так что вы можете видеть, как я пришел к такому выводу. Есть идеи?


1) Укажите значение hiveconf для простого запроса

(должна быть дата для окончательного запроса)

hive -e "Select  ${hiveconf:dateRangeFrom} , unix_timestamp(${hiveconf:dateRangeFrom} , 'yyyy-MM-dd');"  --hiveconf dateRangeFrom='2014-01-01'

Дата будет возвращена как предоставленная и преобразована в метку времени Unix (например, "2014-01-01" = 1388534400, "2014-09-12" = 41047640). Сценарий может быть запущен несколько раз с изменением результатов в соответствии с параметром.

2) Создайте представление, которое возвращает эти данные

CREATE VIEW get_date AS 
SELECT  ${hiveconf:dateRangeFrom}, unix_timestamp(${hiveconf:dateRangeFrom} , 'yyyy-MM-dd');

Это возвращает ошибку:

FAILED: ParseException line 2:8 cannot recognize input near '$' '{' 'hivevar' in  select clause

Предположительно, потому что он пытается выполнить замену, но переменная $ {hivevar: dateRangeFrom} не была инициализирована на данный момент

Согласно с: Создание видов в Hive с параметром и http://mail-archives.apache.org/mod_mbox/hive-user/201205.mbox/%[email protected]%3E

Затем переменные можно использовать в представлениях Hive, если вокруг них используются кавычки:

CREATE VIEW get_date AS 
SELECT  "${hiveconf:dateRangeFrom}", unix_timestamp("${hiveconf:dateRangeFrom}" , 'yyyy-MM-dd');

Это позволяет создавать представление, поэтому пытаемся вызвать представление с помощью параметра:

hive -e "Select  * from get_date"  --hiveconf dateRangeFrom='2014-01-01'

просто возвращает имя переменной:

${hiveconf:dateRangeFrom}       NULL
    Time taken: 20.614 seconds, Fetched: 1 row(s)

Вместо этого используйте одинарные кавычки:

DROP VIEW get_date;
CREATE VIEW get_date AS 
SELECT  '${hiveconf:dateRangeFrom}', unix_timestamp('${hiveconf:dateRangeFrom} ', 'yyyy-MM-dd');

Дает тот же результат, только имя переменной.

3) Создайте представление в интерактивном сеансе с уже установленной переменной

SET hiveconf:dateRangeFrom="2014-02-01";

Восстановить исходный вид с переменными без кавычек

DROP VIEW get_date;
CREATE VIEW get_date AS 
SELECT  ${hiveconf:dateRangeFrom}, unix_timestamp(${hiveconf:dateRangeFrom} , 'yyyy-MM-dd');

Затем вызывается "select * from get_date;" изнутри сеанса дает ожидаемый результат.

Как и при вызове из командной строки, с тем же значением параметра:

hive -e "Select  * from get_date;"  --hiveconf dateRangeFrom='2014-02-01'

Однако, если мы вызовем представление с другим параметром, мы все равно получим исходный ответ:

hive -e "Select  * from get_date;"  --hiveconf dateRangeFrom='2014-09-12'

    2014-02-01      1391212800
    Time taken: 24.773 seconds, Fetched: 1 row(s)

Если мы установим переменную внутри нового сеанса:

SET hiveconf:dateRangeFrom="2014-06-01";

или даже не устанавливая все это, мы все равно получаем тот же результат

Глядя на определение расширенного представления, причина очевидна:

hive> describe extended get_date;
OK
_c0                     string
_c1                     bigint

Detailed Table Information      Table(tableName:get_date, dbName:default, owner:
36015to, createTime:1410523149, lastAccessTime:0, retention:0, sd:StorageDescrip
tor(cols:[FieldSchema(name:_c0, type:string, comment:null), FieldSchema(name:_c1
, type:bigint, comment:null)], location:null, inputFormat:org.apache.hadoop.mapr
ed.SequenceFileInputFormat, outputFormat:org.apache.hadoop.hive.ql.io.HiveSequen
ceFileOutputFormat, compressed:false, numBuckets:-1, serdeInfo:SerDeInfo(name:nu
ll, serializationLib:null, parameters:{}), bucketCols:[], sortCols:[], parameter
s:{}, skewedInfo:SkewedInfo(skewedColNames:[], skewedColValues:[], skewedColValu
eLocationMaps:{}), storedAsSubDirectories:false), partitionKeys:[], parameters:{
transient_lastDdlTime=1410523149}, ***viewOriginalText:SELECT  "2014-02-01", unix_t
imestamp("2014-02-01" , 'yyyy-MM-dd'), viewExpandedText:SELECT  "2014-02-01", un
ix_timestamp("2014-02-01" , 'yyyy-MM-dd')***, tableType:VIRTUAL_VIEW)
Time taken: 0.123 seconds, Fetched: 4 row(s)

Замена переменных произошла при создании представления и жестко закодировала эту дату в определении:

viewOriginalText: ВЫБЕРИТЕ "2014-02-01", unix_t   imestamp ("2014-02-01", 'гггг-ММ-дд'), viewExpandedText: ВЫБРАТЬ "2014-02-01", un   ix_timestamp ("2014-02-01", 'yyyy-MM-dd')

4) Отключить переменную подстановку

Hive явно вводит текущее значение переменной во время выполнения, поэтому я попытался отключить его и заново создать запрос:

hive> set hive.variable.substitute;
hive.variable.substitute=true
hive> set hive.variable.substitute = false;
hive> set hive.variable.substitute;
hive.variable.substitute=false

Оператор Create View по-прежнему не выполняется с той же ошибкой:

FAILED: ParseException line 2:8 cannot recognize input near '$' '{' 'hiveconf' in select clause

5) Обходной путь

Если мы создадим файл sql, который создает представления, testParam.sql, мы сможем обойти проблему:

DROP VIEW get_date;
CREATE VIEW get_date AS
SELECT  ${hivevar:dateRangeFrom}, unix_timestamp(${hivevar:dateRangeFrom} , 'yyyy-MM-dd');
SELECT * FROM get_date;

Вызов этого из командной строки дает ожидаемые результаты:

hive -f testParam.sql --hiveconf dateRangeFrom='2014-08-01'
2014-08-01      1406847600
Time taken: 20.763 seconds, Fetched: 1 row(s)


hive -f testParam.sql --hiveconf dateRangeFrom='2014-09-12'
2014-09-12      1410476400
Time taken: 19.74 seconds, Fetched: 1 row(s)    

Это работает, и пока будет хорошо, но вряд ли идеально подходит для распределенной многопользовательской среды. Глядя на метаданные представления, мы видим, что представление всегда уничтожается и перестраивается с последними параметрами:

transient_lastDdlTime=1410525287}, viewOriginalText:SELECT  '2014-09-12', unix_timestamp('2014-09-12' , 'yyyy-MM-dd'), viewExpandedText:SELECT  '2014-09-12', unix_timestamp('2014-09-12' , 'yyyy-MM-dd'), tableType:VIRTUAL_VIEW)

Итак, как создать представление, которое может быть снабжено динамическими параметрами во время выполнения, не перестраивая его постоянно

Ответ 1

Как вы определяете daterangeFrom? Я думаю, что daterange from может динамически генерироваться из current_date, добавляя и вычитая дни, основываясь на ваших требованиях. Вы можете просто использовать для этого функции hive.

Ответ 2

Я не хочу, если это то, что вы ищете! если вы передаете значения из bash script, это должно выполнить задание:

dateRangeFrom=$(date +"%Y-%m-%d")
hive -e "Select  '${dateRangeFrom}' , unix_timestamp('${dateRangeFrom}' , 'yyyy-MM-dd');"

Если вы хотите установить значение в куст script, вы можете сделать что-то вроде этого

hive -e "SET hivevar:dateRangeFrom=2017-11-21;USE mydb; Select  '${dateRangeFrom}' , unix_timestamp('${dateRangeFrom}' , 'yyyy-MM-dd');"

Если вы хотите сохранить один и тот же запрос куста в HQL файле и запустить его извне, то вам нужно передать его так:

hive -f /abc/user/script.hql --hivevar dateRangeFrom=2017-11-21