Skip to content

46.1。 PL/Python 函数#

PL/Python 中的函数通过标准CREATE FUNCTION语法声明

CREATE FUNCTION funcname (argument-list)
  RETURNS return-type
AS $$
  # PL/Python function body
$$ LANGUAGE plpython3u;

函数的主体只是一个 Python 脚本。当调用函数时,其参数作为列表args的元素传递;命名参数也作为普通变量传递给 Python 脚本。通常,使用命名参数更具可读性。结果以通常的方式从 Python 代码返回,使用returnyield(在结果集语句的情况下)。如果您不提供返回值,Python 将返回默认None。PL/Python将 Python 的None转换为 SQL null 值。在过程中,Python 代码的结果必须为None(通常通过在没有return语句的情况下结束过程或使用没有参数的return语句来实现);否则,将引发错误。

例如,可以将函数定义为返回两个整数中的较大者

CREATE FUNCTION pymax (a integer, b integer)
  RETURNS integer
AS $$
  if a > b:
    return a
  return b
$$ LANGUAGE plpython3u;

作为函数定义主体给出的 Python 代码将转换为 Python 函数。例如,上述结果为

def __plpython_procedure_pymax_23456():
  if a > b:
    return a
  return b

假设 23456 是PostgreSQL分配给该函数的 OID。

参数设置为全局变量。由于 Python 的作用域规则,这有一个微妙的后果,即不能在函数内部将参数变量重新赋值为涉及变量名称本身的表达式的值,除非在块中将变量重新声明为全局。例如,以下内容不起作用

CREATE FUNCTION pystrip(x text)
  RETURNS text
AS $$
  x = x.strip()  # error
  return x
$$ LANGUAGE plpython3u;

因为对x进行赋值会使x成为整个块的局部变量,因此赋值右侧的x引用尚未分配的局部变量x,而不是 PL/Python 函数参数。使用global语句,可以使其工作

CREATE FUNCTION pystrip(x text)
  RETURNS text
AS $$
  global x
  x = x.strip()  # ok now
  return x
$$ LANGUAGE plpython3u;

但建议不要依赖 PL/Python 的此实现细节。最好将函数参数视为只读。