↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2

第 46 章 PL/Python — Python 过程语言

PL/Python过程语言允许使用Python 语言编写PostgreSQL函数和过程。

要在特定数据库中安装 PL/Python,可使用CREATE EXTENSION plpython3u。

提示

如果把某种语言安装到template1中,之后创建的所有数据库都会自动安装该语言。

PL/Python 只能作为一种“不受信任的”语言使用,这意味着它不提供任何机制来限制用户能在其中做什么,因此其名称为plpython3u。如果将来能在 Python 中开发出安全的执行机制,受信任的变体plpython可能会出现。使用不受信任的 PL/Python 编写函数时,函数编写者必须确保该函数不会被用来做任何不希望发生的事情,因为它能够做到任何以数据库管理员身份登录的用户所能做的事情。只有超级用户才能在plpython3u这类不受信任的语言中创建函数。

注意

源码包用户必须在安装过程中专门启用 PL/Python 的构建(更多信息请参阅安装说明)。二进制包用户则可能会在单独的子包中找到 PL/Python。

46.1. PL/Python 函数 #

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

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

函数体只是一个 Python 脚本。调用函数时,其参数会作为列表args的元素传入;命名参数还会作为普通变量传给 Python 脚本。使用命名参数通常可读性更好。结果通常通过return或yield(在返回结果集的情况下)从 Python 代码返回。如果不提供返回值,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()  # 错误
  return x
$$ LANGUAGE plpython3u;

因为对x赋值会使x在整个代码块中都成为局部变量,因此赋值语句右侧的x指向的是尚未赋值的局部变量x,而不是 PL/Python 函数参数。使用global语句后,这样写就能工作:

CREATE FUNCTION pystrip(x text)
  RETURNS text
AS $$
  global x
  x = x.strip()  # 现在可以正常工作
  return x
$$ LANGUAGE plpython3u;

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

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。英文原文本身的问题请通过上游文档表单反馈给 PostgreSQL 文档维护者。