Postgresql 中文操作指南
46.1. PL/Python Functions #
PL/Python 中的函数通过标准 CREATE FUNCTION 语法声明:
CREATE FUNCTION funcname (argument-list)
RETURNS return-type
AS $$
# PL/Python function body
$$ LANGUAGE plpython3u;
函数的主体就是一个 Python 脚本。当调用该函数时,其参数作为列表 args 的元素传递;命名参数也作为普通变量传递至 Python 脚本。通常来说,使用命名参数可读性更高。结果会以通常的方式(在结果集语句中使用 return 或 yield)从 Python 代码返回。如果不提供返回值,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 的此项实现细节。最好将函数参数视为只读。