×
Мы обрабатываем cookies, чтобы сделать наш сайт удобнее и персонализированнее для вас. Подробнее: политика использования «cookies» и «политики конфиденциальности».

Для самостоятельной настройки ознакомьтесь с инструкцией

Дополнительные настройки cookies в браузерах

Файлы cookie автоматически загружаются в ваш браузер при посещении веб-сайта. У вас есть возможность управлять этими файлами. Если Вы не согласны с использованием файлов cookies, запретите их сохранение на своём устройстве, удалите уже имеющиеся файлы cookies через настройки браузера или прекратите использование сайта.

При отключении обработки cookie наш сайт продолжит функционировать, однако будут использоваться исключительно необходимые технические файлы, без которых работа ресурса невозможна.

Инструкция по отключению cookies
Принять
Настроить
Отклонить

ДОКУМЕНТАЦИЯ

Выберите версию, форк и язык для СУБД Digital Q.DataBase, чтобы прочитать или скачать всю документацию.
Техподдержка
Документация
Диасофт
Авторские права © 2016–2025 ООО "Диасофт Экосистема"
Скачать всю документацию:

5.9.2. Значения данных

5.9.2.1. Сопоставление типов данных
5.9.2.2. Null, None
5.9.2.3. Массивы и списки
5.9.2.4. Составные типы
5.9.2.5. Функции, возвращающие наборы

В целом, цель PL/Python заключается в предоставлении «естественного» сопоставления между мирами PostgreSQL и Python. Это лежит в основе правил сопоставления данных, описанных ниже.

5.9.2.1. Сопоставление типов данных #

При вызове функции на PL/Python её аргументы преобразуются из типа данных PostgreSQL в соответствующий тип Python:

  • PostgreSQL boolean преобразуется в тип Python bool.

  • PostgreSQL smallint, int, bigint и oid преобразуются в тип Python int.

  • PostgreSQL real и double преобразуются в Python float.

  • PostgreSQL numeric преобразуется в Python Decimal. Этот тип импортируется из пакета cdecimal если он доступен. В противном случае decimal.Decimal из стандартной библиотеки будет использован. cdecimal значительно быстрее чем decimal. Начиная с Python 3.3, однако, cdecimal был интегрирован в стандартную библиотеку под именем decimal, поэтому разницы больше нет.

  • PostgreSQL bytea преобразуется в тип Python bytes.

  • Все остальные типы данных, включая строковые типы PostgreSQL, преобразуются в тип Python str (в кодировке Unicode, как и все строки Python).

  • Для нескалярных типов данных см. ниже.

Когда функция PL/Python завершает выполнение, возвращаемое значение преобразуется в объявленный тип данных PostgreSQL следующим образом:

  • Если возвращаемый тип PostgreSQL — boolean, то возвращаемое значение будет проверяться на истинность согласно Python правилам. То есть, 0 и пустая строка трактуются как ложь (false), но, что примечательно, 'f' трактуется как истина (true).

  • Если возвращаемый тип PostgreSQL — bytea, возвращаемое значение будет преобразовано в формат Python bytes с использованием соответствующих встроенных средств Python, а полученный результат будет преобразован в bytea.

  • Для всех остальных возвращаемых типов PostgreSQL значение преобразуется в строку с помощью встроенной функции Python str, после чего результат передается входной функции соответствующего типа данных PostgreSQL. (Если значение Python представляет собой float, оно преобразуется с использованием пакета repr вместо встроенной функции str, чтобы избежать потери точности.)

    Строки автоматически преобразуются в кодировку сервера PostgreSQL при их передаче в PostgreSQL.

  • Для нескалярных типов данных см. ниже.

Обратите внимание, что логические несоответствия между объявленным типом возвращаемого значения PostgreSQL и типом данных Python фактически возвращаемого объекта не фиксируются; значение будет преобразовано в любом случае.

5.9.2.2. Null, None #

Если значение NULL в SQL передается в функцию, значение аргумента будет представлено как None в Python. Например, определение функции pymax показанное в Раздел 5.9.1 вернет неверный результат для входных данных NULL. Мы могли бы добавить STRICT в определение функции, чтобы Digital Q.DataBase сделать поведение более логичным: если передано значение 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 plpython3u;

Как показано выше, чтобы вернуть значение NULL в SQL из функции PL/Python, следует возвращать значение None. Это можно сделать независимо от того, помечена ли функция как STRICT или нет.

5.9.2.3. Массивы и списки #

Значения массивов SQL передаются в PL/Python как список Python. Чтобы вернуть значение массива SQL из функции PL/Python, необходимо вернуть список Python:

CREATE FUNCTION return_arr()
  RETURNS int[]
AS $$
return [1, 2, 3, 4, 5]
$$ LANGUAGE plpython3u;

SELECT return_arr();
 return_arr
-------------
 {1,2,3,4,5}
(1 row)

Многомерные массивы передаются в PL/Python как вложенные списки Python. Например, двумерный массив — это список списков. При возврате многомерного массива SQL из функции PL/Python внутренние списки на каждом уровне должны иметь одинаковый размер. Например:

CREATE FUNCTION test_type_conversion_array_int4(x int4[]) RETURNS int4[] AS $$
plpy.info(x, type(x))
return x
$$ LANGUAGE plpython3u;

SELECT * FROM test_type_conversion_array_int4(ARRAY[[1,2,3],[4,5,6]]);
INFO:  ([[1, 2, 3], [4, 5, 6]], <type 'list'>)
 test_type_conversion_array_int4
---------------------------------
 {{1,2,3},{4,5,6}}
(1 строка)

Другие последовательности Python, такие как кортежи, также поддерживаются для обратной совместимости с PostgreSQL версий 9.6 и ниже, в которых многомерные массивы не поддерживались. Однако они всегда обрабатываются как одномерные массивы, так как в противном случае они неотличимы от составных типов. По этой же причине, когда составной тип используется в многомерном массиве, он должен быть представлен кортежем, а не списком.

Обратите внимание, что в Python строки являются последовательностями, что может привести к нежелательным эффектам, знакомым разработчикам на Python:

CREATE FUNCTION return_str_arr()
  RETURNS varchar[]
AS $$
return "hello"
$$ LANGUAGE plpython3u;

SELECT return_str_arr();
 return_str_arr
----------------
 {h,e,l,l,o}
(1 строка)

5.9.2.4. Составные типы #

Аргументы составных типов передаются функции в виде отображений (mappings) 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 plpython3u;

Существует несколько способов возврата строк или составных типов из функции на языке 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 plpython3u;

Чтобы вернуть SQL NULL для любого столбца, вставьте None None в соответствующую позицию.

Если возвращается массив составных типов, он не может быть возвращен в виде списка, поскольку невозможно однозначно определить, представляет ли список Python составной тип или другую размерность массива.

Отображение (словарь)

Значение для каждого столбца результирующего типа извлекается из отображения с использованием имени столбца в качестве ключа. Пример:

CREATE FUNCTION make_pair (name text, value integer)
  RETURNS named_value
AS $$
  return { "name": name, "value": value }
$$ LANGUAGE plpython3u;

Любые лишние пары ключ/значение в словаре игнорируются. Отсутствие ключей считается ошибкой. Чтобы вернуть значение NULL в SQL для любого столбца, вставьте None 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)

  # or simply
  class nv: pass
  nv.name = name
  nv.value = value
  return nv
$$ LANGUAGE plpython3u;

Функции с OUT параметрами также поддерживаются. Например:

CREATE FUNCTION multiout_simple(OUT i integer, OUT j integer) AS $$
return (1, 2)
$$ LANGUAGE plpython3u;

SELECT * FROM multiout_simple();

Выходные параметры процедур передаются обратно тем же способом. Например:

CREATE PROCEDURE python_triple(INOUT a integer, INOUT b integer) AS $$
return (a * 3, b * 3)
$$ LANGUAGE plpython3u;

CALL python_triple(5, 10);

5.9.2.5. Функции, возвращающие наборы #

PL/Python- 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 plpython3u;

Итератор (любой объект, предоставляющий __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 plpython3u;

Генератор (yield)

CREATE FUNCTION greet (how text)
  RETURNS SETOF greeting
AS $$
  for who in [ "World", "PostgreSQL", "PL/Python" ]:
    yield ( how, who )
$$ LANGUAGE plpython3u;

Функции, возвращающие набор (set-returning functions), с OUT параметрами (использующие RETURNS SETOF record) также поддерживаются. Например:

CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$
return [(1, 2)] * n
$$ LANGUAGE plpython3u;

SELECT * FROM multiout_simple_setof(3);

Наверх
свяжитесь
с нами
контакты
Для прямой связи с нами вы можете использовать контакты ниже, либо оставить заявку через форму обратной связи, и мы обязательно свяжемся с вами

*поля обязательные к заполнению