2014-02-08 71 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