> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-86180b7b.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Пользовательские функции в Cloud

> Добавьте в Cloud собственные исполняемые функции Python

export const galaxyOnClick = eventName => () => {
  try {
    if (typeof window !== "undefined" && window.galaxy && eventName) {
      window.galaxy.track(eventName, {
        interaction: "click"
      });
    }
  } catch (e) {}
};

export const BetaBadge = ({link, galaxyTrack, galaxyEvent}) => {
  if (link) {
    return <a href={link} target="_blank" rel="noopener noreferrer" className="betaBadge" onClick={galaxyTrack && galaxyEvent ? galaxyOnClick(galaxyEvent) : undefined}>
                <Icon />
                <span>Beta</span>
            </a>;
  }
  return <div className="betaBadge">
            <Icon />
            <span>
                Beta feature. 
                <u>
                    <a href="/docs/beta-and-experimental-features#beta-features">
                        Learn more.
                    </a>
                </u>
            </span>
        </div>;
};

Пользовательские функции (UDF) позволяют расширять возможности ClickHouse сверх того, что доступно в более чем тысяче готовых [функций](/ru/reference/functions/regular-functions/regular-functions-index).

В ClickHouse Cloud есть два способа создать пользовательские функции:

1. С помощью SQL
2. С помощью интерфейса и собственного кода (публичная бета)

<div id="sql-udfs">
  ## Пользовательские функции SQL
</div>

Пользовательские функции SQL можно создавать с помощью оператора [`CREATE FUNCTION`](/ru/reference/statements/create/function) на основе лямбда-выражения.

В этом примере мы создадим простую исполняемую пользовательскую функцию `isBusinessHours`.
Функция будет проверять, попадает ли указанная временная метка в стандартные рабочие часы, и возвращать true, если да, и false — если нет.

1. Войдите в Cloud Console и откройте консоль SQL
2. Напишите следующий SQL-запрос, чтобы создать функцию `isBusinessHours`:

```sql theme={null}
CREATE FUNCTION isBusinessHours AS (ts) ->
toDayOfWeek(ts) BETWEEN 1 AND 5
AND toHour(ts) BETWEEN 9 AND 17;
```

3. Чтобы протестировать только что созданную UDF, выполните следующую команду:

```sql theme={null}
SELECT isBusinessHours('2026-03-20 10:00:00'::DateTime), isBusinessHours('2026-03-20 23:00:00'::DateTime);
```

Вы должны получить такой результат:

```response theme={null}
1   0
```

4. Вы можете использовать команду `DROP FUNCTION`, чтобы удалить только что созданную UDF:

```sql theme={null}
DROP FUNCTION isBusinessHours
```

<Warning>
  **Важно**

  пользовательская функция (UDF) в ClickHouse Cloud **не наследует настройки на уровне пользователя**. Она выполняется с системными настройками по умолчанию.
</Warning>

Это означает:

* Настройки уровня сеанса (заданные через оператор `SET`) не передаются в контекст выполнения UDF
* Настройки профиля пользователя не наследуются UDF
* Настройки уровня запроса не применяются при выполнении UDF

<div id="ui-udfs">
  ## Пользовательские функции, созданные через интерфейс
</div>

ClickHouse Cloud позволяет создавать пользовательские функции через интерфейс.

В этом примере мы создадим ту же простую исполняемую пользовательскую функцию `isBusinessHours`, которая проверяет, попадает ли заданная временная метка в обычные рабочие часы.
Ранее мы создавали её с помощью SQL, а на этот раз создадим её с помощью Python и настроим через интерфейс.

<Steps>
  <Step>
    ### Создайте Python-файл

    Создайте новый файл `main.py` на локальной машине:

    ```python theme={null}
    cat > main.py << 'EOF'
    import sys
    from datetime import datetime

    for line in sys.stdin:
        ts = datetime.fromisoformat(line.strip())
        result = 1 if (0 <= ts.weekday() <= 4 and 9 <= ts.hour <= 17) else 0
        print(result)
        sys.stdout.flush()
    EOF
    ```

    Если ваш Python-скрипт импортирует сторонние пакеты, необходимо создать файл `requirements.txt` со списком зависимостей. Например:

    ```text theme={null}
    requests>=2.28.0
    numpy>=1.23.0
    ```

    <Note>
      ClickHouse Cloud ожидает, что в zip-архиве, который вы загрузите через интерфейс на следующем шаге, будет файл `main.py`.
      Если назвать файл иначе, возникнет ошибка.
    </Note>
  </Step>

  <Step>
    ### Пакеты зависимостей и локальные файлы

    Чтобы включить пакеты зависимостей и любые дополнительные локальные файлы (например, wheel-файлы, файлы конфигурации или файлы данных), поместите их в тот же каталог, где находятся `main.py` и `requirements.txt`. При создании ZIP-архива включите в него все файлы:

    ```bash theme={null}
    zip is_business_hours.zip main.py requirements.txt
    ```

    В коде Python вы можете сослаться на базовый каталог локального упакованного path, используя `os.path.dirname(os.path.abspath(__file__))`. Это возвращает абсолютный path к каталогу, в котором находится ваш `main.py` внутри ZIP-архива, что позволяет получать доступ к другим упакованным файлам:

    ```python theme={null}
    import os

    # Получить базовый каталог упакованных файлов
    base_dir = os.path.dirname(os.path.abspath(__file__))
    config_path = os.path.join(base_dir, 'config.json')
    ```

    Это полезно, когда вам нужно:

    * Получить доступ к файлам конфигурации, включённым в ваш UDF
    * Загрузить wheel-пакеты для пользовательских зависимостей
    * Указать дополнительные скрипты или файлы данных

    Теперь сожмите файл в ZIP-архив:

    ```bash theme={null}
    zip is_business_hours.zip main.py
    ```

    <Warning>
      **Символические ссылки запрещены**

      ClickHouse Cloud отклоняет архивы UDF, содержащие символические ссылки. Убедитесь, что ваш ZIP-архив содержит только обычные файлы и каталоги — загрузка архивов с символическими ссылками не пройдет проверку.
    </Warning>
  </Step>

  <Step>
    ### Создание UDF через интерфейс

    1. На главной странице Cloud Console нажмите имя вашей организации в меню в левом нижнем углу.
    2. Выберите в меню **Пользовательские функции**.
    3. На странице пользовательских функций нажмите **Настроить UDF**. Справа откроется панель конфигурации.
    4. Введите имя функции. В этом примере используйте `isBusinessHours`.
    5. Выберите тип функции: **Executable pool** или **Executable**:
       * **Executable pool**: Поддерживается пул постоянных процессов, и для операций чтения процесс берётся из этого пула.
       * **Executable**: Скрипт запускается для каждого запроса.
    6. В этом примере используйте настройки по умолчанию. Полный список параметров конфигурации см. в разделе [Исполняемые пользовательские функции](/ru/reference/functions/regular-functions/udf#executable-user-defined-functions).
    7. Нажмите **Выбрать файл**, чтобы загрузить файл `.zip`, созданный в начале этого руководства.
    8. Добавьте новый аргумент. В этом примере добавьте аргумент `timestamp` с типом `DateTime`.
    9. Выберите тип возвращаемого значения. В этом примере выберите `Bool`.
    10. Нажмите **Создать UDF**. В диалоговом окне отобразится текущий статус сборки.
        * Если возникнут какие-либо проблемы, статус изменится на **ошибка**.
        * В противном случае статус последовательно изменится с **сборка** на **подготовка**. Для завершения подготовки ваш сервис должен быть активен. Если сервис находится в состоянии бездействия, нажмите **Пробудить сервис** на панели **Сведения о UDF** рядом с именем сервиса.
        * После завершения статус изменится на **развернуто**.
  </Step>

  <Step>
    ### Протестируйте свою UDF

    1. вернитесь на главную страницу **SQL Console**, нажав в левом верхнем углу страницы **Settings - return to your service view**
    2. нажмите **SQL Console** в меню слева
    3. введите следующий запрос:

    ```sql theme={null}
    SELECT isBusinessHours('2026-03-20 10:00:00'::DateTime), isBusinessHours('2026-03-20 23:00:00'::DateTime);
    ```

    Вы увидите результат:

    ```response theme={null}
    true    false
    ```
  </Step>

  <Step>
    ### Создайте новую версию

    1. На главной странице Cloud Console нажмите имя своей организации в меню в левом нижнем углу.
    2. В меню выберите **Пользовательские функции**.
    3. Для UDF `isBusinessHours` нажмите на три точки в разделе **Действия**, затем выберите **Создать новую версию**
    4. Загрузите ZIP-архив с измененным кодом или измените настройки, затем нажмите **Создать новую версию**

    Вы успешно добавили свою первую пользовательскую функцию через интерфейс, убедились, что она выполняется, и узнали, как при необходимости создать для нее новую версию.
  </Step>
</Steps>
