我开始在Redshift中学习Python用户定义函数,我有几个问题需要澄清。假设我定义了以下函数:
CREATE OR REPLACE FUNCTION f_parse_url_query_string(url VARCHAR(MAX))
RETURNS varchar(max)
STABLE
AS $$
from urlparse import urlparse, parse_qsl
import json
return json.dumps(dict(parse_qsl(urlparse(url)[4])))
$$ LANGUAGE plpythonu;
它是要在每次调用函数时运行imports
,还是由Redshift编译并只导入一次?在
我的第二个问题是是否有方法返回变量数据类型。例如,如果我想创建一个获取嵌套json字段值的函数,结果可以是从字符串到整数或布尔值的任何值。有没有办法在函数返回类型上创建一个自动检测?在
进口
是和否。Redshift在语句中重用udf执行环境(甚至可能在整个事务中,但我还没有测试过)。的确,每次在处理import语句时调用函数时都会处理import语句,cpython会快速检查模块是否已经导入,如果已经导入,则使用已经导入的模块。像这样的函数本地(后期)导入经常被用来解决循环依赖问题,因此必须执行。我还通过执行以下操作来解决udf中缺少全局初始化的问题:
if '_cache' not in globals(): import thing globals()['_cache'] = thing.build_cache() return _cache.get(arg)
这不是我在任何地方都会做的事情,但这并不是一个通用代码。在
关于udf的执行环境,它显然是简单的细节,不应该过于依赖,但实际上它不太可能很快发生实质性的变化。不能保证任何特定进程的生存时间/它将处理多少行,但让它们尽可能长时间地存在是符合他们的利益的,因为cpython进程(和容器)的创建并不完全便宜——当然对于每一行来说都太重了。它们依赖lxc进行隔离,并为您提供了一个真正的(如果沙盒中有沙盒的话)linux环境来执行(如果您仔细考虑的话,这对于用户安装的本机扩展来说是非常必要的)。文件系统上甚至有一些文档可供那些想挖掘的人使用:)
返回值
虽然返回值的数据类型不能更改redshift(now?)支持参数和返回类型的ANYELEMENT数据类型。正如前面的回答所描述的,它仍然需要一个消除歧义的类型化参数,因为仍然不支持返回类型多态性,但它至少为您省去了为每个要返回的类型创建单独函数的麻烦。在
执行
是的,每次都会执行
import
。在避免这种情况的一种方法是使用
IMMUTABLE
作为函数的挥发性。这使得Redshift可以为给定的输入值缓存函数的输出,从而避免了以后对相同输入值运行Python函数的需要。在返回值
返回值的数据类型是固定的,不能更改。可以为不同的函数名或不同的输入类型定义不同的返回值(例如,定义一个接受整数并返回整数的函数,然后定义另一个名称相同但返回字符串的字符串输入类型的函数输出)。在
另外,使用返回不同输出数据类型的函数是非常困难的——调用UDF的SQL语句需要的是特定的数据类型,而不是更改的数据类型。在
相关问题 更多 >
编程相关推荐