受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

44.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 脚本。使用命名参数通常可读性更好。结果通常通过returnyield(在返回结果集的情况下)从 Python 代码返回。如果不提供返回值,Python 会返回默认值NonePL/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 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 的这一实现细节。最好将函数参数视为只读。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。