Функции на PL/Python объявляются с помощью стандартного CREATE FUNCTION синтаксиса:
CREATE FUNCTIONимя_функции(список_аргументов) RETURNSтип_результатаAS $$ # тело функции на PL/Python $$ LANGUAGE plpython3u;
Тело функции представляет собой обычный скрипт на языке Python. При вызове функции её аргументы передаются как элементы списка
args; именованные аргументы также передаются в скрипт Python как обычные переменные. Использование именованных аргументов обычно повышает читаемость кода. Результат возвращается из кода Python обычным способом с помощью return или
yield (в случае инструкции, возвращающей набор результатов). Если возвращаемое значение не указано, Python возвращает стандартное значение
None. PL/Python которое преобразует
значение Python None в значение NULL в 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 — это OID, присвоенный данной функции Digital Q.DataBase.
Аргументы задаются как глобальные переменные. В силу правил определения областей видимости в Python это влечёт за собой специфическое последствие: переменной аргумента нельзя присвоить внутри функции значение выражения, использующего имя этой же переменной, если только она не будет объявлена в данном блоке как глобальная (global). Например, следующий код не будет работать:
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. Лучше рассматривать параметры функции как доступные только для чтения.