gpt4 book ai didi

hadoop - 无法在 Hive 查询中定义动态参数

转载 作者:可可西里 更新时间:2023-11-01 14:11:37 29 4
gpt4 key购买 nike

我正在尝试在 Hive 中设置一些将日期作为动态参数的 View 。在我下面的工作中,我已经切换到在 Select 子句中使用 hiveconf 变量,因此我们可以看到发生了什么,但原理保持不变

根据 thisthis ,我应该能够在我的 Create View 语句中的“${hiveconf:dateRangeFrom}”中包含一个语句,在运行时提供 hiveconf:dateRangeFrom 变量以获得最大的快乐,但这只是没有发生 - Hive 似乎正在使用任何东西值在创建 View 并将其硬编码到 View 定义中时分配给变量,而不是像您期望的那样在运行时替换它。

我有一个解决方法,我向一个 sql 文件提供一个参数,然后创建所有 View ,替换所需的值,但这不可持续

所有的工作都在下面,所以你可以看到我是如何得出这个结论的。有任何想法吗?

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)创建一个返回此数据的 View
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} 变量尚未初始化

根据:
Creating Views in Hive with parameter
http://mail-archives.apache.org/mod_mbox/hive-user/201205.mbox/%3CBAY151-W9BC976D584FD172E7D70BC0160@phx.gbl%3E

然后可以在 Hive View 中使用变量,只要在它们周围使用引号:
CREATE VIEW get_date AS 
SELECT "${hiveconf:dateRangeFrom}", unix_timestamp("${hiveconf:dateRangeFrom}" , 'yyyy-MM-dd');

这允许创建 View ,因此尝试使用参数调用 View :
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) 在已经设置变量的交互式 session 中创建一个 View
SET hiveconf:dateRangeFrom="2014-02-01";

重建原始 View ,变量不带引号
DROP VIEW get_date;
CREATE VIEW get_date AS
SELECT ${hiveconf:dateRangeFrom}, unix_timestamp(${hiveconf:dateRangeFrom} , 'yyyy-MM-dd');

然后调用“select * from get_date;”从 session 中给出了预期的结果。

与从命令行调用一样,使用相同的参数值:
hive -e "Select  * from get_date;"  --hiveconf dateRangeFrom='2014-02-01'

但是,如果我们使用不同的参数调用 View ,那么我们仍然得到原始答案:
hive -e "Select  * from get_date;"  --hiveconf dateRangeFrom='2014-09-12'

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

如果我们在新 session 中设置变量:
SET hiveconf:dateRangeFrom="2014-06-01";

甚至不全部设置,我们仍然得到相同的结果

查看扩展 View 定义,原因很明显:
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)

变量替换发生在 View 创建时,并将该日期硬编码到定义中:

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')

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) 解决方法

如果我们创建一个创建 View 的 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)

这确实有效,并且目前还可以,但对于分布式多用户环境来说并不理想。查看 View 元数据,我们可以看到 View 总是被销毁并使用最新的参数重建:
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)

那么,如何创建一个可以在运行时提供动态参数而不需要不断重建它的 View

最佳答案

你如何定义daterangeFrom?我认为 daterange from 可以通过根据您的要求添加和减去天数从 current_date 函数动态生成。您可以简单地使用 hive 函数。

关于hadoop - 无法在 Hive 查询中定义动态参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25809124/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com