| Документация по PostgreSQL 9.4.1 | |||
|---|---|---|---|
| Пред. | Уровень выше | Глава 43. PL/Python — процедурный язык Python | След. |
43.3. Значения данных
Вообще говоря, цель исполнителя PL/Python — обеспечить "естественное" соответствие между мирами PostgreSQL и Python. Этим объясняется выбор правил сопоставления данных, описанных ниже.
43.3.1. Сопоставление типов данных
Аргументы функций преобразуются из типа PostgreSQL в соответствующий тип Python по таким правилам:
Тип PostgreSQL boolean преобразуется в bool языка Python.
Типы PostgreSQL smallint и int преобразуются в тип int языка Python. Типы PostgreSQL bigint и oid становятся типами long в Python 2 и int в Python 3.
Типы PostgreSQL real и double преобразуются в тип float языка Python.
Тип PostgreSQL numeric преобразуется в Decimal среды Python. Этот тип импортируется из пакета cdecimal, при его наличии. В противном случае используется decimal.Decimal из стандартной библиотеки. Тип cdecimal работает значительно быстрее, чем decimal. Однако в Python 3.3 тип cdecimal был включён в стандартную библиотеку под именем decimal, так что теперь этого различия нет.
Тип PostgreSQL bytea становится типом str в Python 2 и bytes в Python 3. В Python 2 такую строку следует воспринимать как последовательность байт без какой-либо определённой кодировки символов.
Все другие типы данных, включая типы символьных строк PostgreSQL, преобразуются в тип str языка Python. В Python 2 эта строка будет передаваться в кодировке сервера PostgreSQL; в Python 3 это будет строка в Unicode, как и все строки.
Информация о нескалярных типах данных приведена ниже.
Значения, возвращаемые функцией, преобразуются в тип данных, объявленный как тип результата в PostgreSQL, следующим образом:
Когда тип результата функции в PostgreSQL — boolean, возвращаемое значение приводится к логическому типу по правилам, принятым в Python. То есть false будет возвращено для 0 и пустой строки, но, обратите внимание, для 'f' будет возвращено true.
Когда тип результата функции PostgreSQL — bytea, возвращаемое значение будет преобразовано в строку (Python 2) или набор байт (Python 3), используя встроенные средства Python, а затем будет приведено к типу bytea.
Для всех других типов результата PostgreSQL возвращаемое значение Python преобразуется в строку с помощью встроенной в Python функции str, и полученная строка передаётся функции ввода типа данных PostgreSQL.
В Python 2, строки должны передаваться в PostgreSQL в кодировке сервера PostgreSQL. При передаче строки, неприемлемой для текущей кодировки сервера, возникает ошибка, но не все несоответствия кодировки могут быть выявлены, так что с некорректной кодировкой всё же могут быть получены нечитаемые строки. Строки Unicode переводятся в нужную кодировку автоматически, так что использовать их может быть безопаснее и удобнее. В Python 3 все строки имеют кодировку Unicode.
Информация о нескалярных типах данных приведена ниже.
Обратите внимание, что логические несоответствия между объявленным в PostgreSQL типом результата и типом Python фактического возвращаемого объекта игнорируются — значение преобразуется в любом случае.
43.3.2. Null, None
Если функции передаётся значение SQL NULL, в Python значением этого аргумента будет None. Например, функция pymax, определённая как показано в Раздел 43.2, возвратит неверный ответ, получив аргументы NULL. Мы могли бы добавить указание STRICT в определение функции, чтобы PostgreSQL поступал немного разумнее: при передаче значения NULL функция вовсе не будет вызываться, будет сразу возвращён результат NULL. С другой стороны, мы могли бы проверить аргументы на NULL в теле функции:
CREATE FUNCTION pymax (a integer, b integer)
RETURNS integer
AS $$
if (a is None) or (b is None):
return None
if a > b:
return a
return b
$$ LANGUAGE plpythonu;Как показано выше, чтобы выдать из функции PL/Python значение SQL NULL, нужно вернуть значение None. Это можно сделать и в строгой, и в нестрогой функции.
43.3.3. Массивы, списки
Значения массивов SQL передаются в PL/Python в виде списка Python. Чтобы вернуть массив SQL из функции PL/Python, возвратите последовательность Python, например, список или кортеж:
CREATE FUNCTION return_arr()
RETURNS int[]
AS $$
return (1, 2, 3, 4, 5)
$$ LANGUAGE plpythonu;
SELECT return_arr();
return_arr
-------------
{1,2,3,4,5}
(1 row)Учтите, что в Python и строки являются последовательностями, что может давать неожиданные эффекты, хорошо знакомые тем, кто программирует на Python:
CREATE FUNCTION return_str_arr()
RETURNS varchar[]
AS $$
return "hello"
$$ LANGUAGE plpythonu;
SELECT return_str_arr();
return_str_arr
----------------
{h,e,l,l,o}
(1 row)43.3.4. Составные типы
Аргументы составного типа передаются функции в виде сопоставлений Python. Именами элементов сопоставления являются атрибуты составного типа. Если атрибут в переданной строке имеет значение NULL, он передаётся в сопоставлении значением None. Пример работы с составным типом:
CREATE TABLE employee (
name text,
salary integer,
age integer
);
CREATE FUNCTION overpaid (e employee)
RETURNS boolean
AS $$
if e["salary"] > 200000:
return True
if (e["age"] < 30) and (e["salary"] > 100000):
return True
return False
$$ LANGUAGE plpythonu;Возвратить составной тип или строку таблицы из функции Python можно несколькими способами. В следующих примерах предполагается, что у нас объявлен тип:
CREATE TYPE named_value AS ( name text, value integer );
Результат этого типа можно вернуть как:
- Последовательность (кортеж или список, но не множество, так как оно не индексируется)
В возвращаемых объектах последовательностей должно быть столько элементов, сколько полей в составном типе результата. Элемент с индексом 0 присваивается первому полю составного типа, с индексом 1 — второму и т. д. Например:
CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return [ name, value ] # или в виде кортежа: return ( name, value ) $$ LANGUAGE plpythonu;
Чтобы выдать SQL NULL для какой-нибудь колонки, вставьте в соответствующую позицию None.
- Сопоставление (словарь)
Значение колонки результата получается из сопоставления, в котором ключом является имя колонки. Например:
CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return { "name": name, "value": value } $$ LANGUAGE plpythonu;Любые дополнительные пары ключ/значение в словаре игнорируются, а отсутствие нужных ключей считается ошибкой. Чтобы выдать SQL NULL для какой-нибудь колонки, вставьте None с именем соответствующей колонки в качестве ключа.
- Объект (любой объект с методом __getattr__)
Объект передаётся аналогично сопоставлению. Пример:
CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ class named_value: def __init__ (self, n, v): self.name = n self.value = v return named_value(name, value) # или просто class nv: pass nv.name = name nv.value = value return nv $$ LANGUAGE plpythonu;
Также поддерживаются функции с параметрами OUT (выходными). Например:
CREATE FUNCTION multiout_simple(OUT i integer, OUT j integer) AS $$ return (1, 2) $$ LANGUAGE plpythonu; SELECT * FROM multiout_simple();
43.3.5. Функции, возвращающие множества
Функция PL/Python также может возвращать множества, содержащие скалярные и составные типы. Это можно осуществить разными способами, так как возвращаемый объект внутри превращается в итератор. В следующих примерах предполагается, что у нас есть составной тип:
CREATE TYPE greeting AS ( how text, who text );
Множество в качестве результата можно возвратить, применив:
- Последовательность (кортеж, список, множество)
CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ # возвращает кортеж, содержащий списки в качестве составных типов # также будут работать и остальные комбинации return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] ) $$ LANGUAGE plpythonu;
- Итератор (любой объект, реализующий методы __iter__ и next)
CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ class producer: def __init__ (self, how, who): self.how = how self.who = who self.ndx = -1 def __iter__ (self): return self def next (self): self.ndx += 1 if self.ndx == len(self.who): raise StopIteration return ( self.how, self.who[self.ndx] ) return producer(how, [ "World", "PostgreSQL", "PL/Python" ]) $$ LANGUAGE plpythonu;- Генератор (yield)
CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ for who in [ "World", "PostgreSQL", "PL/Python" ]: yield ( how, who ) $$ LANGUAGE plpythonu;Внимание Из-за ошибки 1483133 в Python, некоторые отладочные версии Python 2.4 (сконфигурированные и скомпилированные с ключом --with-pydebug) выводят из строя сервер PostgreSQL, когда итератор возвращает набор результатов. Эта ошибка проявляется в неисправленных версиях Fedora 4, но не в выпускаемых версиях Python и в исправленной Fedora 4.
Также поддерживаются функции, возвращающие множества, с параметрами OUT (объявленные с RETURNS SETOF record). Например:
CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$ return [(1, 2)] * n $$ LANGUAGE plpythonu; SELECT * FROM multiout_simple_setof(3);
| Пред. | Начало | След. |
| Функции на PL/Python | Уровень выше | Совместное использование данных |