您的位置:寻梦网首页编程乐园数据库PostgreSQL 7.2 Documentation

26.3. 使用 PL/Python

这里是在 plpython_function.sql 里的简单函数.你写的 Python 代码转换成一个函数.也就是

CREATE FUNCTION myfunc(text) RETURNS text AS
'return args[0]'
LANGUAGE 'plpython';

转换成

def __plpython_procedure_myfunc_23456():
    return args[0]

这里的 23456 是这个函数的 Oid.

如果你没有提供返回数值,Python 返回缺省的 None , 这个可能是你想要的,也可能不是.这个语言模块把 Python 的 None 转换成 SQL 的 NULL.

PostgreSQL 函数变量可以通过全局的 args 列表获取. 在 myfunc 例子里, args[0] 包含当做文本参数传递的数值.对于 myfunc2(text, integer) args[0] 将包含 text 变量和整数变量 args[1]

全局字典 SD 可以用于在函数调用中间存储数据. 这个变量是私有静态数据.全局字典 GD 是公共数据, 可以在一个后端里的所有 python 函数之间使用. 用时小心.

每个函数都在 Python 解释器里获得自己的受限制的执行对象, 因此来自 myfunc 的全局数据很函数参数 是 myfunc2 所看不到的.这里的例外是 我们上面提到的 GD 字典.

当一个函数用做触发器的时候,字典 TD 包含事务相关的数值. 触发器元组在 TD["new"] 和/或 TD["old"] 里面,具体情况取决于 触发器事件.TD["event"] 中包含以字串形式出现的事件 ("INSERT", "UPDATE", "DELETE", 或 "UNKNOWN").TD["when"] 包含 ("BEFORE", "AFTER", 或者 "UNKNOWN") 之一. TD["level"] 包含 ("ROW", "STATEMENT", 或者 "UNKNOWN")之一. TD["name"] 包含触发器名字,而 TD["relid"] 包含触发器发生的 表的关系标识.如果触发器是带着参数调用的,那么这些参数可以 通过TD["args"][0] 到 TD["args"][(n -1)] 获得.

如果触发器的 'when' 是 "BEFORE",那么你可以从 python 函数返回 'None' 或者 "OK" 以表示该元组没有修改,返回 "SKIP" 以退出事件, 或者 "MODIFIED" 表示你已经修改了该元组.

PL/Python 语言模块自动输入一个叫 plpy 的 Python 模块.在这个模块里的函数和常量可以在你的 Python 代码里 以 plpy. foo 的 名字获得.目前, plpy 实现了函数 plpy.error("msg") plpy.fatal("msg") plpy.debug("msg") , 和 plpy.notice("msg") . 它们非常类似调用 elog( LEVEL , "msg") , 这里的 LEVEL 是 DEBUG,ERROR,FATAL 或者 NOTICE. plpy.error plpy.fatal 实际上抛出一个 Python 例外,如果你没有捕获这个例外,会导致 在函数句柄从 Python 解释器返回的时候 PL/Python 模块对 elog(ERROR, msg) 的调用. 从 Python 解释器里长跳转出去可能是不太好的事情. raise plpy.ERROR("msg") raise plpy.FATAL("msg") 等效于调用 plpy.error 或者 plpy.fatal

另外, plpy 模块提供两个函数,叫 execute prepare . 拿一个查询字串和一个可选的限制参数调用 plpy.execute 可以运行该查询,并且结果返回 到一个结果对象里.结果对象仿真一个列表或者一个字典对象. 结果对象可以通过行号和字段号来访问.它有下面这些额外的方法∶ nrows() 返回该查询返回的行数, 而 status SPI_exec 的返回变量.结果对象可能被修改.

rv = plpy.execute("SELECT * FROM my_table", 5)

返回来自 my_table 中最多 5 行.如果 my_table 有一个 my_field 字段, 那么你可以用下面的方法访问它

foo = rv[i]["my_field"]

第二个函数 plpy.prepare 是带一个查询字串 和一个参数类型列表(如果你在该查询里有绑定变量)调用的,

plan = plpy.prepare("SELECT last_name FROM my_users WHERE first_name = $1", [ "text" ])

text 是你将作为 $1 传递的变量的类型.在准备之后,你用 函数 plpy.execute 运行它.

rv = plpy.execute(plan, [ "name" ], 5)

限制参数在调用 plpy.execute 时是可选的.

在你用 PL/Python 模块准备一个计划的时候,该计划是自动保存的. 请阅读 SPI 文档( Chapter 21 ) 获取这句话的含义. 要注意的事情是,如果你做了

plan = plpy.prepare("SOME QUERY")
plan = plpy.prepare("SOME OTHER QUERY")

那么你就在漏内存,据我所知,没有什么办法来施放一个保存了的规划. 另外一种使用非保存规划的方法甚至(对我而言)更痛苦.