PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

44.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 的常规方式 返回,使用 return 或 yield(对于结果集语句)。如果不提供返回值, Python 会返回默认的 None。 PL/Python 把 Python 的 None 翻译为 SQL 空值。在过程中,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 的这个实现细节。最好把函数参数当作 只读的。