2014-02-08 38 views
5

我想在两个或多个PL/Python函数之间声明和共享一些简单的纯Python函数,这些函数在 之间。我正在使用Postgres 9.3。在PL/Python函数之间重复使用纯Python函数

例如,我有:

CREATE OR REPLACE FUNCTION get_mod(modifier varchar) 
    RETURNS varchar 
    AS $$ 
     def is_float(val): 
     try: 
      if val: 
       float(val) 
       return True 
      else: 
       return False 
     except ValueError: 
      return False 
     if modifier is None: 
     return "NOMOD" 
     if is_float(modifier): 
     return str(float(modifier)*1) 
     return modifier 
    $$ LANGUAGE plpythonu; 

我想在其他一些PL/Python函数使用功能is_float。 我知道我可以将它创建为可调用的PL/Python函数,但是我发现它比对纯Python(自定义实用函数)直接调用更加笨拙(对PL/Python执行基于SQL的调用)。

是否可以在Postgres上通过PL/Python可重用的纯Python函数创建和公开?

回答

4

我通常所做的就是通过使用GD来传递函数。缺点是由于GD是每个会话对象,每次开始新会话时都需要加载它。您可以采用的方法是在每个会话开始时运行引导程序功能,以便进一步使用数据库。喜欢的东西:

create or replace function bootstrap() returns void 
as 
$$ 
def is_float(val): 
    # did some simplifying here, 
    try: 
    float(val) # Take notice that booleans will convert to float successfully 
    return True 
    except (ValueError, TypeError): 
    return False 

GD['is_float'] = is_float 
$$ language plpythonu; 

现在,您可以修改原来的功能:

CREATE OR REPLACE FUNCTION get_mod(modifier varchar) 
RETURNS varchar 
    AS $$ 
     # Optionally run bootstrap() here 
     plpy.execute("select bootstrap()") 
     ### 
     if modifier is None: 
     return "NOMOD" 
     if GD['is_float'](modifier): 
     return str(float(modifier)*1) 
     return modifier 
    $$ LANGUAGE plpythonu; 

为了这个工作,你不得不在每个会话开始运行select bootstrap();,或作为的一部分作为流程的一部分调用的第一个函数...或实际上作为原始函数的一部分。

0

一个选项是创建一个模块,然后导入它。您可以按照here所述将其位置添加到PYTHONPATH,以确保运行时可以找到它。

+0

是的,这看起来是唯一的选择,除非我想混乱OID黑客。 – Edmon