6

我想在两个或多个 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、自定义实用程序函数要笨重得多(执行基于 SQL 的 PL/Python 调用)。

是否可以在 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 回答
1

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

于 2014-02-08T04:19:57.767 回答