Python UDF
Experimental feature
В этом разделе описывается, как разрабатывать пользовательские функции (UDF) с использованием Python.
Начиная с версии 3.4.0, Selena поддерживает создание Python UDF.
В настоящее время Selena поддерживает только скалярные UDF на Python.
Предварительные требования
Перед началом работы убедитесь, что выполнены следующие требования:
- Установлен Python 3.8 или более поздняя версия.
- UDF включены в Selena путём установки параметра
enable_udfв значениеtrueв файле конфигурации FE fe/conf/fe.conf, после чего необходимо перезапустить узлы FE для применения конфигурации. Подробнее см. Конфигурация FE - enable_udf. - Для Python UDF требуется пакет pyarrow.
- Установите местоположение среды интерпретатора Python в экземпляре BE с помощью переменной окружения. Добавьте переменную
python_envsи установите её значение в путь установки интерпретатора Python, например,/opt/Python-3.8/.
Разработка и использование Python UDF
Синтаксис:
CREATE [GLOBAL] FUNCTION function_name(arg_type [, ...])
RETURNS return_type
{PROPERTIES ("key" = "value" [, ...]) | key="value" [...] }
[AS $$ $$]
| Параметр | Обязательный | Описание |
|---|---|---|
| GLOBAL | Нет | Создать ли глобальную UDF. |
| function_name | Да | Имя создаваемой функции. Вы можете включить имя базы данных в этот параметр, например, db1.my_func. Если function_name содержит имя базы данных, UDF создаётся в этой базе данных. В противном случае UDF создаётся в текущей базе данных. Имя новой функции и её параметры не должны совпадать с существующим именем в целевой базе данных. В противном случае функция не может быть создана. Создание выполняется успешно, если имя функции совпадает, но параметры отличаются. |
| arg_type | Да | Тип аргумента функции. Добавленный аргумент может быть представлен как , .... Поддерживаемые типы данных см. в Соответствие между типами данных SQL и Python. |
| return_type | Да | Тип возвращаемого значения функции. Поддерживаемые типы данных см. в Соответствие между типами данных SQL и Python. |
| PROPERTIES | Да | Свойства функции, которые зависят от типа создаваемой UDF. |
| AS $$ $$ | Нет | Укажите встроенный код UDF между метками $$. |
Свойства включают:
| Свойство | Обязательное | Описание |
|---|---|---|
| type | Да | Тип UDF. Значение Python указывает на создание UDF на основе Python. |
| symbol | Да | Имя класса для проекта Python, к которому принадлежит UDF. Значение этого параметра имеет формат <package_name>.<class_name>. |
| input | Нет | Тип входных данных. Допустимые значения: scalar (по умолчанию) и arrow (векторизованный ввод). |
| file | Нет | HTTP-URL, по которому можно загрузить файл пакета Python, содержащий код для UDF. Значение этого параметра имеет формат http://<http_server_ip>:<http_server_port>/<python_package_name>. Обратите внимание, что имя пакета должно иметь суффикс .py.zip. Значение по умолчанию: inline, что означает создание встроенной UDF. |
Создание встроенной скалярной UDF с использованием Python
Следующий пример создаёт встроенную функцию echo со скалярным вводом с использованием Python.
CREATE FUNCTION python_echo(INT)
RETURNS INT
type = 'Python'
symbol = 'echo'
file = 'inline'
AS
$$
def echo(x):
return x
$$
;
Создание встроенной векторизованной UDF с использованием Python
Поддерживается векторизованный ввод для повышения производительности обработки UDF.
Следующий пример создаёт встроенную функцию add с векторизованным вводом с использованием Python.
CREATE FUNCTION python_add(INT)
RETURNS INT
type = 'Python'
symbol = 'add'
input = "arrow"
AS
$$
import pyarrow.compute as pc
def add(x):
return pc.add(x, 1)
$$
;
Создание пакетной UDF с использованием Python
При создании пакета Python вы должны упаковать модуль в файлы .py.zip, которые должны соответствовать формату zipimport.
> tree .
.
├── main.py
└── yaml
├── composer.py
├── constructor.py
├── cyaml.py
├── dumper.py
├── emitter.py
├── error.py
├── events.py
├── __init__.py
├── loader.py
├── nodes.py
├── parser.py
> cat main.py
import numpy
import yaml
def echo(a):
return yaml.__version__
CREATE FUNCTION py_pack(string)
RETURNS string
symbol = "add"
type = "Python"
file = "http://HTTP_IP:HTTP_PORT/m1.py.zip"
symbol = "main.echo"
;