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

# Funciones definidas por el usuario en Cloud

> Añada sus propias funciones ejecutables en Python en Cloud

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}>
                <span>Beta</span>
            </a>;
  }
  return <a href="https://clickhouse.com/docs/reference/settings/beta-and-experimental-features#beta-features" className="betaBadge">
            <span>Funcionalidad beta</span>
        </a>;
};

Las funciones definidas por el usuario (UDF) permiten ampliar el comportamiento de ClickHouse más allá de lo que ofrecen las más de mil [funciones](/es/reference/functions/regular-functions/overview) integradas.

En ClickHouse Cloud, hay varias formas de crear y administrar funciones definidas por el usuario:

1. Mediante SQL
2. Mediante la UI y su propio código (beta pública)
3. Mediante la [Cloud API](#manage-udfs-with-the-cloud-api) (beta)
4. Mediante [Terraform](#manage-udfs-with-terraform) (alpha)

<div id="sql-udfs">
  ## Funciones definidas por el usuario en SQL
</div>

Las UDF de SQL se pueden crear con la sentencia [`CREATE FUNCTION`](/es/reference/statements/create/function) a partir de una expresión lambda.

En este ejemplo, crearemos una función definida por el usuario ejecutable sencilla, `isBusinessHours`.
La función comprobará si un timestamp determinado está dentro del horario laboral habitual y devolverá true si es así; de lo contrario, false.

1. Inicie sesión en Cloud Console y abra la consola SQL
2. Escriba la siguiente consulta SQL para crear la función `isBusinessHours`:

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

3. Ejecute lo siguiente para probar la UDF que acaba de crear:

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

Deberías obtener este resultado:

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

4. Puede usar el comando `DROP FUNCTION` para eliminar la UDF que acaba de crear:

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

<Warning>
  **Importante**

  Las UDF en ClickHouse Cloud **no heredan la configuración a nivel de usuario**. Se ejecutan con la configuración predeterminada del sistema.
</Warning>

Esto significa:

* La configuración a nivel de sesión (establecida mediante la instrucción `SET`) no se propaga al contexto de ejecución de las UDF
* Las UDF no heredan la configuración del perfil de usuario
* La configuración a nivel de consulta no se aplica durante la ejecución de las UDF

<div id="ui-udfs">
  ## Funciones definidas por el usuario creadas desde la UI
</div>

<BetaBadge />

ClickHouse Cloud permite crear funciones definidas por el usuario desde la UI.

En este ejemplo, crearemos la misma función ejecutable simple definida por el usuario `isBusinessHours`, que comprueba si una marca temporal determinada cae dentro del horario laboral habitual.
Anteriormente la creamos mediante SQL, pero esta vez la crearemos con Python y la configuraremos desde la UI.

<Steps>
  <Step title="Crear el archivo de Python" id="create-python-file">
    Crea un nuevo archivo `main.py` localmente:

    ```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
    ```

    Si tu script de Python importa paquetes de terceros, inclúyelos en un archivo `requirements.txt` y ClickHouse Cloud los instalará por ti. También puedes empaquetar las dependencias directamente en el archivo ZIP, pero entonces debes incluir paquetes en caché para ambas arquitecturas de CPU, así que `requirements.txt` es más sencillo. Por ejemplo:

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

    <Note>
      ClickHouse Cloud espera encontrar `main.py` en el archivo zip que cargarás a través de la UI en el siguiente paso.
      Si le das otro nombre al archivo, se producirá un error.
    </Note>
  </Step>

  <Step title="Empaquetar dependencias y archivos locales" id="bundle-dependencies">
    Para incluir los paquetes de dependencias y cualquier archivo local adicional (como archivos wheel, archivos de configuración o archivos de datos), colóquelos en el mismo directorio que `main.py` y `requirements.txt`. Al crear el archivo ZIP, incluya todos los archivos:

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

    Puedes referenciar el directorio base de la ruta local incluida en tu código Python usando `os.path.dirname(os.path.abspath(__file__))`. Esto devuelve la ruta absoluta del directorio donde se encuentra tu `main.py` dentro del archivo ZIP, lo que te permite acceder a otros archivos incluidos:

    ```python theme={null}
    import os

    # Get the base directory of the bundled files
    base_dir = os.path.dirname(os.path.abspath(__file__))
    config_path = os.path.join(base_dir, 'config.json')
    ```

    Esto es útil cuando necesitas:

    * Acceder a los archivos de configuración incluidos con tu UDF
    * Cargar paquetes wheel para dependencias personalizadas
    * Incluir scripts adicionales o archivos de datos

    Ahora comprime el archivo en un archivo ZIP:

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

    <Warning>
      **No se permiten enlaces simbólicos**

      ClickHouse Cloud rechaza los archivos comprimidos de UDF que contienen enlaces simbólicos. Asegúrate de que tu paquete ZIP contenga solo archivos y directorios normales; las cargas con enlaces simbólicos no pasarán la validación.
    </Warning>
  </Step>

  <Step title="Crear una UDF desde la UI" id="create-udf-via-ui">
    1. En la página principal de Cloud Console, haz clic en el nombre de tu organización en el menú de la esquina inferior izquierda.
    2. Selecciona **Funciones definidas por el usuario** en el menú.
    3. En la página de funciones definidas por el usuario, haz clic en **Configurar una UDF**. Se abrirá un panel de configuración a la derecha de la pantalla.
    4. Introduce un nombre para la función. Para este ejemplo, usa `isBusinessHours`.
    5. Selecciona un tipo de función: **Executable pool** o **Executable**:
       * **Executable pool**: Se mantiene un grupo de procesos persistentes y, para las lecturas, se toma un proceso del grupo.
       * **Executable**: El script se ejecuta en cada consulta.
    6. Para este ejemplo, usa la configuración predeterminada. Para ver la lista completa de parámetros de configuración, consulta [Funciones ejecutables definidas por el usuario](/es/reference/functions/regular-functions/udf#executable-user-defined-functions).
    7. Haz clic en **Buscar archivo** para cargar el archivo `.zip` que creaste al inicio de este tutorial.
    8. Añade un argumento nuevo. Para este ejemplo, añade un argumento `timestamp` de tipo `DateTime`.
    9. Selecciona un tipo de retorno. Para este ejemplo, selecciona `Bool`.
    10. Haz clic en **Crear UDF**. Un cuadro de diálogo mostrará el estado actual de la compilación.
        * Si surge algún problema, el estado cambia a **error**.
        * En caso contrario, el estado pasa de **building** a **provisioning**. Tu servicio debe estar activo para completar el aprovisionamiento. Si tu servicio está inactivo, haz clic en **Activar servicio** en el panel **Detalles de la UDF** junto al nombre del servicio.
        * Cuando se complete, el estado cambia a **deployed**.
  </Step>

  <Step title="Prueba tu UDF" id="test-your-udf">
    1. vuelve a la página de inicio de la SQL Console haciendo clic en **Settings - volver a la vista de tu servicio** en la esquina superior izquierda de la página
    2. haz clic en **SQL Console** en el menú de la izquierda
    3. escribe la siguiente consulta:

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

    Deberías ver el siguiente resultado:

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

  <Step title="Crear una nueva versión" id="create-new-version">
    Para cambiar el código de una UDF, crea una nueva versión. El panel **Edit** solo gestiona a qué servicios está asignada una UDF; cargar un archivo allí no reemplazará el código desplegado.

    1. En la página principal de Cloud Console, haz clic en el nombre de tu organización en el menú de la esquina inferior izquierda.
    2. Selecciona **Funciones definidas por el usuario** en el menú.
    3. En **Acciones**, selecciona los tres puntos de la UDF `isBusinessHours` y haz clic en **Crear nueva versión**
    4. Sube un archivo ZIP con el código modificado o cambia la configuración y, a continuación, haz clic en **Crear nueva versión**

    Has añadido correctamente tu primera función definida por el usuario a través de la UI, has comprobado que funciona y has visto cómo crear una nueva versión si es necesario.
  </Step>
</Steps>

<div id="manage-udfs-with-the-cloud-api">
  ## Administrar UDFs con la Cloud API
</div>

<BetaBadge />

Todo lo disponible en la UI también está disponible mediante programación a través de la [ClickHouse Cloud API](/es/products/cloud/features/admin-features/api/api-overview).
Los endpoints de UDF permiten automatizar todo el ciclo de vida de una UDF: cargar archivos fuente, crear funciones y versiones, adjuntarlas a servicios y eliminarlas.

<Note>
  Estos endpoints están en beta y el contrato de la API puede cambiar.
</Note>

El flujo de trabajo habitual para crear y desplegar una UDF mediante la API es:

1. [Crear una URL de carga](/es/products/cloud/api-reference/udf/udf-upload-session-create) para obtener una URL prefirmada para cargar archivos `application/zip` y, a continuación, cargar en ella su archivo ZIP. Cada ID de carga solo puede utilizarse para un intento de creación o de versión; solicite una nueva URL de carga al reintentar.
2. [Crear la UDF](/es/products/cloud/api-reference/udf/udf-create) a partir del archivo cargado, especificando el nombre de la función, el runtime, los argumentos y el tipo de retorno.
3. [Adjuntar la UDF a un servicio](/es/products/cloud/api-reference/udf/udf-attach). Si se omite la versión, se adjunta la versión lista más reciente. El servicio debe estar en ejecución; primero se pueden activar los servicios inactivos.

El conjunto completo de endpoints:

| Endpoint                                                                                    | Descripción                                                                                    |
| ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| [Crear URL de carga de UDF](/es/products/cloud/api-reference/udf/udf-upload-session-create) | Crea una URL prefirmada para cargar archivos `application/zip` en el ámbito de la organización |
| [Crear UDF](/es/products/cloud/api-reference/udf/udf-create)                                | Crea una nueva UDF a partir de un archivo cargado                                              |
| [Listar UDFs](/es/products/cloud/api-reference/udf/udf-list)                                | Devuelve la versión más reciente de cada UDF de la organización                                |
| [Obtener UDF](/es/products/cloud/api-reference/udf/udf-get)                                 | Devuelve la versión más reciente de una UDF                                                    |
| [Eliminar UDF](/es/products/cloud/api-reference/udf/udf-delete)                             | Elimina todas las versiones de una UDF y la desvincula de todos los servicios                  |
| [Crear versión de UDF](/es/products/cloud/api-reference/udf/udf-version-create)             | Usa un archivo fuente, asigna una versión e inicia la compilación de la UDF                    |
| [Listar versiones de UDF](/es/products/cloud/api-reference/udf/udf-version-list)            | Devuelve todas las versiones de una UDF                                                        |
| [Eliminar versión de UDF](/es/products/cloud/api-reference/udf/udf-version-delete)          | Elimina una versión de UDF que no está adjunta a ningún servicio                               |
| [Adjuntar UDF a un servicio](/es/products/cloud/api-reference/udf/udf-attach)               | Adjunta una versión de UDF a un servicio y reemplaza la versión actual cuando es necesario     |
| [Listar asociaciones de UDF](/es/products/cloud/api-reference/udf/udf-attachment-list)      | Devuelve las asociaciones actuales de servicios para una UDF                                   |
| [Obtener asociación de UDF](/es/products/cloud/api-reference/udf/udf-attachment-get)        | Devuelve la asociación actual de una UDF con un servicio                                       |
| [Desvincular UDF de un servicio](/es/products/cloud/api-reference/udf/udf-detach)           | Desvincula una UDF de un servicio                                                              |

Consulte la [referencia de la API de UDF](/es/products/cloud/api-reference/udf/udf-create) para ver los esquemas de solicitud y respuesta.

<div id="manage-udfs-with-terraform">
  ## Administrar UDFs con Terraform
</div>

El [proveedor de Terraform de ClickHouse](https://registry.terraform.io/providers/ClickHouse/clickhouse/latest/docs) oficial incluye dos recursos para administrar UDFs como infraestructura como código:

* [`clickhouse_udf`](https://github.com/ClickHouse/terraform-provider-clickhouse/blob/main/docs/resources/udf.md) administra la función propiamente dicha. Recibe un archivo ZIP con el código fuente de la función y publica una nueva versión cada vez que cambia el hash del archivo, esperando a que finalice la compilación.
* [`clickhouse_udf_attachment`](https://github.com/ClickHouse/terraform-provider-clickhouse/blob/main/docs/resources/udf_attachment.md) vincula una versión de una UDF a un servicio. Un servicio puede tener como máximo una versión de una función a la vez. Puede fijar un número de versión o hacer referencia a `clickhouse_udf.<name>.version` para actualizar automáticamente los servicios a la versión más reciente.

<Note>
  Estos recursos están disponibles en la versión 3.24.0 y posteriores del proveedor. Se encuentran en estado alpha y su comportamiento puede cambiar en futuras versiones del proveedor.
</Note>

Por ejemplo, para desplegar con Terraform la UDF `isBusinessHours` del ejemplo anterior:

```terraform theme={null}
resource "clickhouse_udf" "is_business_hours" {
  function_name = "isBusinessHours"
  runtime       = "python3.11"
  type          = "executable_pool"
  return_type   = "Bool"

  arguments = [
    { name = "timestamp", type = "DateTime" },
  ]

  source_archive_path = "${path.module}/is_business_hours.zip"
  source_archive_hash = filebase64sha256("${path.module}/is_business_hours.zip")
}

resource "clickhouse_udf_attachment" "production" {
  function_name = clickhouse_udf.is_business_hours.function_name
  service_id    = var.service_id
  version       = clickhouse_udf.is_business_hours.version
}
```

La vinculación solo se realiza correctamente para las versiones que están listas y puede tardar varios minutos; los servicios inactivos se reactivan automáticamente. Al eliminar un recurso `clickhouse_udf`, se eliminan todas las versiones de la función y se desvincula de todos los servicios.
