43.1. Функции PL/Python#
43.1. Функции PL/Python #
Функции в PL/Python объявляются с использованием стандартного синтаксиса CREATE FUNCTION.
CREATE FUNCTIONfuncname
(argument-list
) RETURNSreturn-type
AS $$ # PL/Python function body $$ LANGUAGE plpython3u;
Тело функции представляет собой простой скрипт на языке Python. При вызове функции ее аргументы передаются в виде элементов списка args
; именованные аргументы также передаются как обычные переменные в скрипт на языке Python. Использование именованных аргументов обычно делает код более читаемым. Результат возвращается из кода на языке Python обычным способом, с помощью операторов return
или yield
(в случае оператора, возвращающего набор результатов). Если вы не предоставляете возвращаемое значение, Python возвращает значение по умолчанию None
. PL/Python преобразует значение None
Python в значение 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 - это OID, присвоенный функции Tantor BE.
Аргументы устанавливаются как глобальные переменные. Из-за правил области видимости в 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. Лучше относиться к параметрам функции как к только для чтения.