Todos los productos
Search
Centro de documentos

Realtime Compute for Apache Flink:Python user-defined scalar functions (UDSFs)

Última actualización: Sep 03, 2026

Una función escalar definida por el usuario (UDSF) asigna cero, uno o más valores escalares a un único valor escalar. Cada fila de entrada produce exactamente un valor de salida.

Este tema describe cómo crear, registrar y utilizar una UDSF de Python en Realtime Compute for Apache Flink.

Límites

A continuación se describen las restricciones aplicables al desarrollar funciones definidas por el usuario (UDF) de Python en Realtime Compute for Apache Flink:

Restricción

Requisito

Versión de Apache Flink

1.12 y posteriores

Versión de Python

Preinstalada en cada espacio de trabajo. VVR anterior a 8.0.11: Python 3.7.9. VVR 8.0.11 y posteriores: Python 3.9.21.

Versión de JDK

JDK 8 y JDK 11. Los paquetes JAR de terceros deben ser compatibles con JDK 8 o JDK 11.

Versión de Scala

Solo Scala 2.11 de código abierto. Los paquetes JAR de terceros deben ser compatibles con Scala 2.11.

Funciones en línea

Compatible solo con VVR 11.9-preview1 y versiones posteriores.

Importante

Después de actualizar a VVR 8.0.11 o posterior, pruebe, despliegue y ejecute nuevamente sus borradores existentes de PyFlink para confirmar su compatibilidad.

Métodos de desarrollo

Puede desarrollar una UDSF de Python de cualquiera de las siguientes maneras:

  • Empaquete su código de Python, cargue el paquete y regístrelo como una función en la plataforma.

  • Declare la lógica del código como una función en línea dentro de una sentencia SQL.

Si la lógica de su UDSF es sencilla, considere desarrollarla como una función en línea.

Crear una UDSF

Los siguientes pasos utilizan Windows como entorno de ejemplo. Flink proporciona un repositorio de ejemplos que incluye implementaciones de UDSF, funciones de agregación definidas por el usuario (UDAF) y funciones con valor de tabla definidas por el usuario (UDTF).
  1. Descargue y descomprima python_demo-master en su computadora local.

    Este es un repositorio de GitHub de terceros. El acceso puede ser lento o intermitente.
  2. En PyCharm, seleccione File > Open y abra el directorio descomprimido python_demo-master.

  3. Abra udfs.py en la ruta \python_demo-master\udx y defina su UDSF.

    from pyflink.table import DataTypes
    from pyflink.table.udf import udf
    
    @udf(result_type=DataTypes.STRING())
    def sub_string(s: str, begin: int, end: int):
        return s[begin:end]

    El ejemplo sub_string extrae caracteres desde la posición begin hasta la posición end en la cadena de entrada.

  4. Desde el directorio \python_demo-master, ejecute el siguiente comando para empaquetar el directorio udx:

    zip -r python_demo.zip udx

    Cuando aparezca python_demo.zip en \python_demo-master\, el paquete está listo.

Registrar una UDSF

Después de crear el paquete, registre la UDSF en la consola de Realtime Compute for Apache Flink. Para consultar los pasos de registro, véase Manage user-defined functions (UDFs).

Utilizar una UDSF

Una vez registrada la UDSF, utilícela en un trabajo de Flink SQL.

  1. Cree un borrador mediante Flink SQL. Para más detalles, consulte Job development overview. El siguiente ejemplo llama a ASI_UDSF (el nombre registrado de su UDSF) para extraer los caracteres de las posiciones 2 a 4 del campo a en la tabla de origen:

    CREATE TEMPORARY TABLE ASI_UDSF_Source (
      a VARCHAR,
      b INT,
      c INT
    ) WITH (
      'connector' = 'datagen'
    );
    
    CREATE TEMPORARY TABLE ASI_UDSF_Sink (
      a VARCHAR
    ) WITH (
      'connector' = 'blackhole'
    );
    
    INSERT INTO ASI_UDSF_Sink
    SELECT ASI_UDSF(a, 2, 4)
    FROM ASI_UDSF_Source;
  2. En el panel de navegación izquierdo de la consola de desarrollo, seleccione O&M > Deployments. Localice el despliegue y haga clic en Start en la columna Actions. Una vez iniciado el despliegue, los caracteres en las posiciones 2–4 del campo a en ASI_UDSF_Source se escriben en ASI_UDSF_Sink.

Funciones escalares en línea de Python

Una función en línea integra su implementación directamente en una sentencia CREATE FUNCTION, por lo que la función se define y registra dentro de la misma sentencia SQL. El siguiente ejemplo define una función en línea que oculta parcialmente direcciones de correo electrónico. Declare la lógica completa del código entre los delimitadores $$.

CREATE TEMPORARY FUNCTION mask_email(email STRING)
RETURNS STRING AS $$
if email is None:
    return None

name, separator, domain = email.partition("@")
if not separator:
    return email

return name[:1] + "***@" + domain
$$ LANGUAGE PYTHON;
Nota
  1. Python es sensible a la sangría. Inicie el código de primer nivel del cuerpo de la función en la columna 0 y mantenga la sangría relativa correcta dentro de los bloques de código.

  2. Las funciones en línea no admiten ejecución vectorizada y no pueden declararse como funciones no deterministas.

  3. Solo se admiten funciones TEMPORARY. Aún no es posible conservar las definiciones de funciones en la plataforma.

Funciones definidas por el usuario asíncronas

Para las UDF que realizan operaciones intensivas en E/S, como el acceso a bases de datos externas o solicitudes HTTP, utilice funciones definidas por el usuario asíncronas. Una sola UDF asíncrona puede gestionar múltiples solicitudes de E/S simultáneamente, lo que distribuye el tiempo de espera entre las solicitudes y mejora el throughput del trabajo.

Límites

  • Compatible solo con VVR 11.7 y versiones posteriores. Se requiere VVR PyFlink 11.7 o superior. Para más detalles, consulte ververica-flink.

    pip3 install "ververica-flink>=11.7"

  • Solo se admiten funciones escalares definidas por el usuario (UDSF) asíncronas.

  • Solo se admite el modo de proceso de Python, es decir, python.execution-mode=process.

  • Las funciones definidas por el usuario asíncronas de Pandas aún no son compatibles.

  • Las funciones en línea aún no son compatibles.

Uso

Una función definida por el usuario asíncrona puede implementarse como una función async de Python o como una subclase de la clase de función asíncrona. A continuación se muestra un código de ejemplo.

import asyncio

from pyflink.table import DataTypes
from pyflink.table.udf import AsyncScalarFunction, udf

# Method 1: Use a Python async function
@udf(result_type=DataTypes.STRING())
async def async_api_call(product_id: str) -> str:
    await asyncio.sleep(0.05)
    return f"product_{product_id}"

# Method 2: Subclass the asynchronous function class
class AsyncUserLookup(AsyncScalarFunction):
    def open(self, function_context):
        self.cache = {}

    async def eval(self, user_id: str) -> str:
        if user_id in self.cache:
            return self.cache[user_id]

        await asyncio.sleep(0.05)
        result = f"user_{user_id}"
        self.cache[user_id] = result
        return result

    def close(self):
        self.cache.clear()

async_user_lookup = udf(
    AsyncUserLookup(),
    input_types=[DataTypes.STRING()],
    result_type=DataTypes.STRING()
)

Las funciones definidas por el usuario asíncronas se registran y utilizan de la misma manera que las funciones síncronas.

Parámetros de configuración

Los siguientes parámetros controlan el comportamiento en tiempo de ejecución de las funciones definidas por el usuario asíncronas.

Parámetro

Valor predeterminado

Descripción

table.exec.async-scalar.max-concurrent-operations

10

Número máximo de llamadas asíncronas simultáneas por instancia de operador. Valor predeterminado: 10.

table.exec.async-scalar.timeout

3 min

Tiempo de espera para una sola llamada asíncrona.

table.exec.async-scalar.retry-strategy

FIXED_DELAY

Estrategia de reintento tras un error en la llamada asíncrona. Valores admitidos:

  • FIXED_DELAY: Reintentar tras un tiempo de espera fijo.

  • NO_RETRY: No reintentar.

table.exec.async-scalar.retry-delay

100 ms

Tiempo de espera para los reintentos con retraso fijo.

Nota

Válido únicamente cuando table.exec.async-scalar.retry-strategy se establece en FIXED_DELAY.

table.exec.async-scalar.max-attempts

3

Número máximo de intentos antes de considerar que una llamada asíncrona ha fallado.

Nota

Válido únicamente cuando table.exec.async-scalar.retry-strategy se establece en FIXED_DELAY.