6

2 つ以上の PL/Python 関数間でいくつかの単純で純粋な Python 関数を宣言して共有したいと考えています。Postgres 9.3 を使用しています。

たとえば、私は持っています:

 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;

is_float関数を他の PL/Python 関数で使用したいと考えています。呼び出し可能な PL/Python 関数として作成できることは理解していますが、純粋な Python のカスタム ユーティリティ関数を直接呼び出すよりも (PL/Python への SQL ベースの呼び出しを実行するために) はるかに扱いにくいことがわかります。

PostgresでPL/Pythonの再利用可能な純粋なPython関数を作成して公開することは可能ですか?

4

2 に答える 2

5

私が通常行うことは、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();には、各セッションの開始時に、またはフローの一部として呼び出す最初の関数の一部として実行する必要があります...または実際には元の関数の一部として。

于 2015-12-24T07:32:56.273 に答える