22.3. 数据库访问

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

另外,plpy 模块提供两个函数,叫 executeprepare. 拿一个查询字串和一个可选的限制参数调用 plpy.execute 可以运行该查询,并且结果返回 到一个结果对象里.结果对象仿真一个列表或者一个字典对象. 结果对象可以通过行号和字段号来访问.它有下面这些额外的方法∶ nrows() 返回该查询返回的行数, 而 statusSPI_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 函数时碰到的任何错误都将导致 服务器马上结束该函数;不可能使用 Python 的try ... catch构造 捕获错误条件.比如,在传递给plpy.execute()调用的 SQL 语句中 的语法错误将终止该函数.这个行为可能在将来的版本中得到修改.

在你用 PL/Python 模块准备一个计划的时候,该计划是自动保存的. 请阅读 SPI 文档(Chapter 17) 获取这句话的含义.

为了能跨函数调用有效地使用这个特点,我们需要使用 永久存储字典 SDGD 之一,参阅 Section 22.1。比如:

CREATE FUNCTION usesavedplan ( ) RETURNS TRIGGER AS '
   if SD.has_key("plan"):
      plan = SD["plan"]
   else:
      plan = plpy.prepare("SELECT 1")
      SD["plan"] = plan
   # rest of function
' LANGUAGE 'plpython';