2014-02-08 17 views
5

Ich möchte einige einfache, reine Python-Funktionen zwischen zwei oder mehr PL/Python-Funktionen deklarieren und teilen. Ich benutze Postgres 9.3.Wiederverwenden von reinen Python-Funktionen zwischen PL/Python-Funktionen

Zum Beispiel habe ich:

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; 

Ich möchte Funktion verwenden is_float in einem anderen PL/Python-Funktion. Ich verstehe, ich könnte es als Callable PL/Python-Funktion erstellen, aber ich finde, dass viel Clunkier (um SQL-basierten Aufruf von PL/Python auszuführen) als nur einen direkten Aufruf an eine reine Python, benutzerdefinierte Dienstprogrammfunktion.

Ist es möglich, durch PL/Python wiederverwendbare reine Python-Funktionen auf Postgres zu erstellen und verfügbar zu machen?

Antwort

4

Was ich normalerweise tue ist, die Funktionen herumzugeben, die GD verwenden. Der Nachteil ist, dass GD ein Session-Objekt ist, das Sie jedes Mal laden müssen, wenn Sie eine neue Session starten. Die Methode, die Sie erreichen können, ist eine Bootstrap-Funktion, die Sie am Anfang jeder Sitzung ausführen, die Primzahlen die Datenbank für die weitere Verwendung. Etwas wie:

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; 

Jetzt können Sie Ihre ursprüngliche Funktion ändern:

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; 

Damit dies funktioniert würde select bootstrap(); zu Beginn jeder Sitzung ausgeführt haben, oder als Teil der erste Funktion, die Sie als Teil des Flusses aufrufen ... oder tatsächlich als Teil Ihrer ursprünglichen Funktion.

0

Eine Option besteht darin, ein Modul zu erstellen und dann zu importieren. Sie können den Standort zu PYTHONPATH wie beschrieben here hinzufügen, um sicherzustellen, dass die Laufzeit es finden kann.

+0

Ja, das scheint die einzige Option zu sein, wenn ich mich nicht mit OID-Hacks anlegen will. – Edmon

Verwandte Themen