选择 打开 改范围 完整检索页
受支持版本: 当前版本 (18) / 17 / 16 / 14
开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10
当前 PostgreSQL 版本不在支持生命周期内。
您可以参阅当前版本的对应页面,或其他在上面列出的活跃大版本。

45.2. PL/Python 函数 #

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

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

函数体就是一段 Python 脚本。调用函数时,参数作为列表 args 的元素传入;命名参数还会作为普通变量传给 Python 脚本。使用命名参数通常更易读。Python 代码按通常方式用 returnyield(返回结果集时)返回结果。如果没有提供返回值,Python 默认返回 NonePL/Python 会将 Python 的 None 转换为 SQL 空值。

例如,一个返回两个整数中较大值的函数可以定义为:

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

函数定义体中给出的 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 plpythonu;

因为对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 plpythonu;

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