45.2. Функции на PL/Python

Функции на PL/Python объявляются стандартным образом с помощью команды CREATE FUNCTION:

CREATE FUNCTION имя_функции (аргументы) RETURNS возвращаемый_тип AS $$ # Тело функции на PL/Python $$ LANGUAGE plpythonu;

Тело функции содержит просто скрипт на языке Python. Когда вызывается функция, её аргументы передаются в виде элементов списка args; именованные аргументы также передаются скрипту Python как обычные переменные. С именованными аргументами скрипт обычно лучше читается. Результат из кода Python возвращается обычным способом: командой return или yield (в случае функции, возвращающей множество). Если возвращаемое значение не определено, Python возвращает None. Исполнитель PL/Python преобразует None языка Python в значение NULL языка 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 — это OID, который PostgreSQL присвоил данной функции.

Значения аргументов задаются в глобальных переменных. Согласно правилам видимости в Python, тонким следствием этого является то, что переменной аргумента нельзя присвоить внутри функции выражение, включающее имя самой этой переменной, если только эта переменная не объявлена глобальной в текущем блоке. Например, следующий код не будет работать:

CREATE FUNCTION pystrip(x text) RETURNS text AS $$ x = x.strip() # ошибка return x $$ LANGUAGE plpythonu;

так как присваивание x значения делает x локальной переменной для всего блока, и при этом x в правой части присваивания оказывается ещё не определённой локальной переменной x, а не параметром функции PL/Python. Добавив оператор global, это можно исправить:

CREATE FUNCTION pystrip(x text) RETURNS text AS $$ global x x = x.strip() # теперь всё в порядке return x $$ LANGUAGE plpythonu;

Однако рекомендуется не полагаться на такие особенности реализации PL/Python, а принять, что параметры функции предназначены только для чтения.

close