Google Datalab - 奇怪的 UDF 扩展
Google Datalab - Weird UDF Expansion
我想引用数据实验室中的现有 UDF。我有这个:
%%bq udf --name interpolate -l js
// A function do liner interpolate
// @param lagValue FLOAT64
// @param leadValue FLOAT64
// @param lagReference FLOAT64
// @param leadReference FLOAT64
// @param currentReference FLOAT64
// @returns FLOAT64
// @import gs://myfilehere.js
return interpolate(lagValue, leadValue, lagReference, leadReference, currentReference);
预期的扩展 SQL 应该是:
CREATE TEMPORARY FUNCTION interpolate (lagValue FLOAT64,leadValue FLOAT64, lagReference FLOAT64,leadReference FLOAT64,currentReference FLOAT64)
RETURNS FLOAT64
LANGUAGE js
AS """
// A function do liner interpolate
// @param lagValue FLOAT64
// @param leadValue FLOAT64
// @param lagReference FLOAT64
// @param leadReference FLOAT64
// @param currentReference FLOAT64
// @returns FLOAT64
// @import gs://myfilehere.js
return interpolate(lagValue, leadValue, lagReference, leadReference, currentReference);
"""
OPTIONS (
library="gs://myfilehere.js"
);
不过,我得到了
CREATE TEMPORARY FUNCTION interpolate (lagReference FLOAT64,leadReference FLOAT64,lagValue FLOAT64,leadValue FLOAT64,currentReference FLOAT64)
RETURNS FLOAT64
LANGUAGE js
AS """
// A function do liner interpolate
// @param lagValue FLOAT64
// @param leadValue FLOAT64
// @param lagReference FLOAT64
// @param leadReference FLOAT64
// @param currentReference FLOAT64
// @returns FLOAT64
// @import gs://myfilehere.js
return interpolate(lagValue, leadValue, lagReference, leadReference, currentReference);
"""
OPTIONS (
library="gs://myfilehere.js"
);
所以,最终的 UDF 参数顺序搞砸了。但是,我通读了源代码,找不到任何真正导致问题的地方。这里需要帮助。 (我使用的是数据实验室版本 1.2.20170525)
此处示例
我的 javascript 插值函数的定义:
function interpolate(lagValue, leadValue, lagReference, leadReference, currentReference)
{
if(lagReference==null)
{
return leadValue;
}
if(leadReference==null)
{
return lagValue;
}
if(Math.abs(leadReference-lagReference) > 0)
{
return lagValue + (((currentReference-lagReference)*(leadValue-lagValue))/(leadReference-lagReference));
}
else
{
return null;
}
};
假设我要在查询中调用插值函数:
%%bq query --udfs interpolate
select interpolate(30,20,1,3,2)
这里正确的 运行 应该是:lagValue=30, leadValue=20, lagReference=1,leadReference=3, currentReference=2.
然而,当 "CREATE TEMPORARY FUNCTION" 部分的参数顺序混乱时,实际发生的情况是这样的:
lagValue=1,leadValue=3,lagReference=30,leadReference=20, currentReference=2.
等式结果错误
这是因为参数被提取到一个字典中,然后那个字典被序列化为一个字符串,这意味着不保留顺序。看看https://github.com/googledatalab/pydatalab/blob/master/google/datalab/bigquery/_udf.py#L96.
这对您造成任何问题吗? BigQuery docs 没有说明需要有序参数。
我想引用数据实验室中的现有 UDF。我有这个:
%%bq udf --name interpolate -l js
// A function do liner interpolate
// @param lagValue FLOAT64
// @param leadValue FLOAT64
// @param lagReference FLOAT64
// @param leadReference FLOAT64
// @param currentReference FLOAT64
// @returns FLOAT64
// @import gs://myfilehere.js
return interpolate(lagValue, leadValue, lagReference, leadReference, currentReference);
预期的扩展 SQL 应该是:
CREATE TEMPORARY FUNCTION interpolate (lagValue FLOAT64,leadValue FLOAT64, lagReference FLOAT64,leadReference FLOAT64,currentReference FLOAT64)
RETURNS FLOAT64
LANGUAGE js
AS """
// A function do liner interpolate
// @param lagValue FLOAT64
// @param leadValue FLOAT64
// @param lagReference FLOAT64
// @param leadReference FLOAT64
// @param currentReference FLOAT64
// @returns FLOAT64
// @import gs://myfilehere.js
return interpolate(lagValue, leadValue, lagReference, leadReference, currentReference);
"""
OPTIONS (
library="gs://myfilehere.js"
);
不过,我得到了
CREATE TEMPORARY FUNCTION interpolate (lagReference FLOAT64,leadReference FLOAT64,lagValue FLOAT64,leadValue FLOAT64,currentReference FLOAT64)
RETURNS FLOAT64
LANGUAGE js
AS """
// A function do liner interpolate
// @param lagValue FLOAT64
// @param leadValue FLOAT64
// @param lagReference FLOAT64
// @param leadReference FLOAT64
// @param currentReference FLOAT64
// @returns FLOAT64
// @import gs://myfilehere.js
return interpolate(lagValue, leadValue, lagReference, leadReference, currentReference);
"""
OPTIONS (
library="gs://myfilehere.js"
);
所以,最终的 UDF 参数顺序搞砸了。但是,我通读了源代码,找不到任何真正导致问题的地方。这里需要帮助。 (我使用的是数据实验室版本 1.2.20170525)
此处示例
我的 javascript 插值函数的定义:
function interpolate(lagValue, leadValue, lagReference, leadReference, currentReference)
{
if(lagReference==null)
{
return leadValue;
}
if(leadReference==null)
{
return lagValue;
}
if(Math.abs(leadReference-lagReference) > 0)
{
return lagValue + (((currentReference-lagReference)*(leadValue-lagValue))/(leadReference-lagReference));
}
else
{
return null;
}
};
假设我要在查询中调用插值函数:
%%bq query --udfs interpolate
select interpolate(30,20,1,3,2)
这里正确的 运行 应该是:lagValue=30, leadValue=20, lagReference=1,leadReference=3, currentReference=2.
然而,当 "CREATE TEMPORARY FUNCTION" 部分的参数顺序混乱时,实际发生的情况是这样的:
lagValue=1,leadValue=3,lagReference=30,leadReference=20, currentReference=2.
等式结果错误
这是因为参数被提取到一个字典中,然后那个字典被序列化为一个字符串,这意味着不保留顺序。看看https://github.com/googledatalab/pydatalab/blob/master/google/datalab/bigquery/_udf.py#L96.
这对您造成任何问题吗? BigQuery docs 没有说明需要有序参数。