无法在配置单元查询中定义动态参数

myzjeezk  于 2021-05-30  发布在  Hadoop
关注(0)|答案(2)|浏览(464)

我正在尝试在配置单元中设置一些视图,这些视图将日期作为动态参数。在我下面的工作中,我已经切换到在select子句中使用hiveconf变量,这样我们就可以看到发生了什么,但是原理是一样的
根据这个和这个,我应该可以在${hiveconf:daterangefrom}“在我的create view语句中,提供hiveconf:daterangefrom variable 为了获得最大的快乐,但这并不是真的——在创建视图时,hive似乎在使用分配给变量的任何值,并将其硬编码到视图定义中,而不是在运行时如您所期望的那样替换它。
我有一个解决方法,我向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}此时尚未初始化变量
根据:使用参数和在配置单元中创建视图http://mail-archives.apache.org/mod_mbox/hive-user/201205.mbox/%3cbay151-w9bc976d584fd172e7d70bc0160@phx.gbl%3e
然后可以在配置单元视图中使用变量,只要在它们周围使用引号:

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\ U 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)

变量替换发生在创建视图时,并将该日期硬编码到定义中:
维奥里ginaltext:select “2014-02-01”,unix时间戳(“2014-02-01”,“yyyy-mm-dd”),viewexpandedtext:select “2014-02-01”,un ix\U时间戳(“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)

那么,如何创建一个在运行时可以提供动态参数的视图,而不必不断地重建它呢

c8ib6hqw

c8ib6hqw1#

您如何定义daterangefrom?我认为daterange from可以根据您的需求,通过对当前的\ date函数进行天数的加减来动态生成。您可以简单地使用配置单元函数。

o7jaxewo

o7jaxewo2#

我不知道这是不是你要找的!如果要从bash脚本传递值,则应该执行以下操作:

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

如果要在配置单元脚本本身中设置值,可以执行以下操作

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

相关问题