A partir de la versión V3.1, Hologres admite llamadas remotas a funciones definidas por el usuario en Function Compute (FC) para procesar lógica de negocio compleja o ejecutar operaciones avanzadas con los datos. En este tema se describe cómo usar las UDF remotas en Hologres.
Descripción general
Las funciones remotas amplían las capacidades de procesamiento y análisis de datos de Hologres mediante la integración de funciones externas de servicios como Alibaba Cloud Function Compute (FC). Esta integración le permite llamar dinámicamente a funciones de FC al consultar datos de Hologres, con el fin de procesar lógica de negocio compleja o ejecutar operaciones avanzadas con los datos.
Las funciones remotas admiten los siguientes casos de uso:
Procesamiento de datos en tiempo real: llame a funciones externas durante las consultas de datos para limpiar datos, convertir formatos o realizar cálculos complejos.
Integración con servicios de terceros: utilice Function Compute para interactuar con otros servicios de Alibaba Cloud o con API de terceros a partir de sus datos de Hologres.
Análisis avanzado: ejecute algoritmos de análisis avanzado en Function Compute, como inference de modelos y aprendizaje automático, y escriba los resultados directamente en Hologres.
Requisitos previos
Cuenta con una instancia de Hologres de la versión V3.1 o posterior. Para obtener más información, consulte Purchase a Hologres instance.
Activó Function Compute y utiliza una instancia de la versión V3.0. Para activar el servicio, inicie sesión en la consola de Function Compute.
-
El rol vinculado al servicio
AliyunServiceRoleForHologresRemoteUDFcuenta con autorización.Inicie sesión en la consola de Hologres. En el panel de navegación izquierdo, haga clic en Create a Service-linked Role.
En el cuadro de diálogo Create Service-Linked Role, busque
AliyunServiceRoleForHologresRemoteUDFy haga clic en Create Service-linked Role debajo del nombre para completar la autorización. Si el rol ya tiene autorización, no se muestra ningún botón y no se requiere ninguna acción.
La instancia de Hologres y el servicio Function Compute deben estar en la misma región.
Active Alibaba Cloud Function Compute, y desarrolle y despliegue la función que llamará Hologres. Para obtener más detalles, consulte Code development overview.
Límites
Solo se admiten UDF escalares y funciones con valores de tabla definidas por el usuario (UDTF). Las funciones agregadas definidas por el usuario (UDAF) no son compatibles.
Solo se admiten los siguientes tipos de datos y sus tipos de arreglo correspondientes:
BOOLEAN,INTEGER,BIGINT,REAL,DOUBLE PRECISIONyTEXT.Las funciones remotas no admiten parámetros de entrada constantes.
Esta función genera costos en Function Compute (FC). Para obtener más información, consulte Billing.
Esta función no genera costos adicionales en Hologres.
-
Las UDF remotas solo se pueden ejecutar en el motor de consultas de Hologres (HQE). No es posible utilizarlas en la misma instrucción SQL junto con funciones integradas que se ejecutan exclusivamente en el motor de consultas compatible con PostgreSQL (PQE), como encryption and decryption (PGCRYPTO) extension functions. Usarlas en conjunto provoca un conflicto de ejecución entre motores y devuelve el siguiente error.
ERROR: ORCA failed to produce a plan : No plan has been computed for required propertiesPara usar una UDF remota y una función integrada exclusiva de PQE al mismo tiempo, divida las operaciones en instrucciones SQL independientes y ejecútelas por separado.
Gestionar UDF remotas
Crear una extensión
Para usar funciones remotas, primero debe crear una extensión mediante la ejecución del siguiente comando:
CREATE EXTENSION [ IF NOT EXISTS ] function_compute;
Crear una función
Sintaxis
CREATE [ OR REPLACE ] FUNCTION <function_name>
( [ [ argmode ] [ argname ] <argtype> [ { DEFAULT | = } default_expr ] [, ...] ] )
[ RETURNS [SETOF] rettype | RETURNS TABLE ( column_name column_type) ]
LANGUAGE function_compute
AS '<fc_endpoint>/<func_name>'
{
{ CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }
| SET function_compute.qualifier TO <qualifier>
| SET function_compute.compression TO <compression>
| SET function_compute.max_batch_size TO <max_batch_size>
} ...
Parámetros
|
Categoría |
Parámetro |
Obligatorio |
Descripción |
|
Nombre de la función |
function_name |
Sí |
El nombre de la función.
|
|
Parámetros de la función |
argtype |
Sí |
El tipo de datos del parámetro. |
|
argmode |
No |
Los valores válidos son IN, OUT e INOUT. El valor predeterminado es IN. Para evitar ambigüedades, se recomienda no usar INOUT. Una función solo puede tener un parámetro OUT o INOUT. |
|
|
argname |
No |
El nombre del parámetro.
|
|
|
default_expr |
No |
El valor predeterminado. Solo aplica a los parámetros de entrada. Si un parámetro tiene un valor predeterminado, todos los parámetros posteriores también deben tenerlo. |
|
|
Endpoint de FC |
LANGUAGE function_compute |
Sí |
Indica que la función utiliza el servicio Function Compute. |
|
fc_endpoint |
Sí |
El endpoint interno de Function Compute. Para obtener más información, consulte Endpoints. |
|
|
func_name |
Sí |
El nombre de la función de destino, la cual debe crearse previamente en la consola de Function Compute. |
|
|
Tipo de valor devuelto |
rettype |
No |
El tipo de datos del valor devuelto. Si utiliza parámetros OUT o INOUT, puede omitir la cláusula RETURNS. Si la especifica, esta cláusula debe coincidir con el tipo de resultado que implican los parámetros de salida. |
|
column_name |
No |
En la sintaxis RETURNS TABLE, representa el nombre de una columna de salida. Es otra forma de declarar parámetros OUT con nombre. La diferencia es que RETURNS TABLE también implica RETURNS SETOF, lo que significa que la función devuelve un conjunto. |
|
|
column_type |
No |
En la sintaxis RETURNS TABLE, representa el tipo de datos de una columna de salida. |
|
|
Política de manejo de valores nulos |
CALLED ON NULL INPUT |
No |
Comportamiento predeterminado. La función se llama incluso si las entradas son NULL y debe manejar la lógica de valores nulos por sí misma. |
|
RETURNS NULL ON NULL INPUT |
No |
Devuelve NULL de inmediato si alguna entrada es NULL. |
|
|
STRICT |
No |
Un alias de RETURNS NULL ON NULL INPUT. |
|
|
Control de versiones de la función |
qualifier |
No |
Especifica la versión o el alias de la función que se va a llamar. El valor predeterminado es |
|
Algoritmo de compresión de solicitudes |
compression |
No |
Especifica el algoritmo de compresión para la solicitud y la respuesta de la llamada a la función. Valores válidos:
|
|
Tamaño máximo de lote por solicitud |
max_batch_size |
No |
Especifica el número máximo de filas que se envían a FC en cada lote. Utilice esta configuración para limitar el tamaño del lote en funciones de FC que tienen restricciones de memoria u otras limitaciones. Si no especifica este parámetro, Hologres calcula automáticamente el tamaño de lote óptimo y lo utiliza. En la mayoría de los casos, no es necesario configurar este parámetro. |
Ejemplos
En los siguientes ejemplos, add y unnest son nombres de funciones en Function Compute, mientras que rf_add y rf_unnest son los nombres de las funciones registradas en Hologres. Antes de ejecutar estas instrucciones, cree las funciones correspondientes en Function Compute y reemplace el endpoint interno y el nombre de la función en la cláusula AS con sus propios valores. Para conocer los formatos de solicitud y respuesta que debe implementar su función, consulte Data exchange format.
-
Cree una UDF escalar.
CREATE OR REPLACE FUNCTION rf_add ( a INTEGER, b INTEGER DEFAULT 1 ) RETURNS BIGINT LANGUAGE function_compute AS 'xxxxxxxxxxxxx.cn-shanghai-internal.fc.aliyuncs.com/add' ; -
Cree una UDTF.
-- Method 1 CREATE OR REPLACE FUNCTION rf_unnest(TEXT []) RETURNS TABLE (item TEXT ) LANGUAGE function_compute AS 'xxxxxxxxxxxxxx.cn-hangzhou-internal.fc.aliyuncs.com/unnest' STRICT SET function_compute.max_batch_size TO 1024; -- Method 2 CREATE OR REPLACE FUNCTION rf_unnest(TEXT []) RETURNS SETOF TEXT LANGUAGE function_compute AS 'xxxxxxxxxxxxxx.cn-hangzhou-internal.fc.aliyuncs.com/unnest' STRICT SET function_compute.max_batch_size TO 1024;
Consultar funciones
Consulte las funciones remotas creadas.
SELECT
CASE
WHEN p.proretset = 'f' THEN 'scalar UDF'
WHEN p.proretset = 't' THEN 'UDTF'
END AS function_type,
n.nspname AS schema_name,
p.proname AS function_name,
pg_get_function_arguments(p.oid) AS arguments,
pg_get_function_result(p.oid) AS return_type,
p.proisstrict AS is_strict,
p.proconfig AS config,
pg_get_functiondef(p.oid) AS definition
FROM
pg_proc p
JOIN pg_language l ON p.prolang = l.oid
JOIN pg_namespace n ON p.pronamespace = n.oid
WHERE
l.lanname = 'function_compute'
AND p.prokind != 'p'
ORDER BY
function_type,
schema_name,
function_name;
Eliminar una función
Sintaxis
DROP FUNCTION [ IF EXISTS ] <function_name> [ ( [ [ argmode ] [ argname ] <argtype> [, ...] ] ) ] [, ...]
Parámetros
|
Parámetro |
Obligatorio |
Descripción |
|
function_name |
Sí |
El nombre de la función que se va a eliminar. |
|
argtype |
Sí |
El tipo de datos del parámetro. |
|
argmode |
No |
Los valores válidos son IN, OUT e INOUT. El valor predeterminado es IN. Para evitar ambigüedades, se recomienda no usar INOUT. Una función solo puede tener un parámetro OUT o INOUT. |
|
argname |
No |
El nombre del parámetro. En los parámetros de entrada, el nombre solo tiene fines de documentación. En los parámetros de salida, el nombre determina el nombre de la columna en el conjunto de resultados. Si se omite, el sistema genera un nombre predeterminado. |
Ejemplo
DROP FUNCTION rf_add(INTEGER, INTEGER);
Formato de intercambio de datos
Formato de solicitud: de Hologres a FC
Hologres llama a la API InvokeFunction de Function Compute mediante el envío de una solicitud POST. El cuerpo de la solicitud es un objeto JSON. Este objeto contiene una única clave llamada data, cuyo valor es un arreglo bidimensional. Cada arreglo interno representa una fila de datos del lote y contiene los parámetros para la llamada a la función.
Reglas de serialización de datos
BOOLEANse serializa como un valor booleano de JSON.INTEGERyBIGINTse serializan como un número de JSON.REALyDOUBLE PRECISIONse serializan como un número de JSON.TEXTse serializa como una cadena de JSON.Un valor SQL
NULLse serializa comonullen JSON.
Ejemplo
A continuación se muestra una solicitud serializada de ejemplo para una función remota con la firma rf_demo(TEXT, INTEGER, BOOLEAN).
{
"data": [
["foo", 100, true],
[null, null, false],
["bar", 200, false]
]
}
Formato de respuesta: de FC a Hologres
Una vez que Function Compute procesa un lote de datos, debe devolver los resultados a Hologres en formato JSON de la siguiente manera:
-
UDF escalar
El objeto de nivel superior debe contener un campo
results. Su valor debe ser un arreglo donde cada elemento corresponde al resultado de una fila de datos de entrada.El resultado de cada fila debe ser un arreglo y el orden de los resultados debe coincidir con el orden de las filas de entrada. Por ejemplo, el enésimo elemento del arreglo de resultados corresponde a la enésima fila de entrada.
A continuación se muestra una respuesta de ejemplo para un lote de cuatro filas:
{ "results": [ ["Beijing"], ["Shanghai"], ["Shenzhen"], ["Guangzhou"] ] } -
Una función con valores de tabla definida por el usuario (UDTF) admite una entrada de una sola fila para generar una salida de varias filas. Se requiere un número de fila (row_num) para identificar la relación con la fila de entrada original.
El objeto de nivel superior debe contener un campo
results. Su valor debe ser un arreglo donde cada elemento corresponde a una fila de datos de salida.-
El resultado de cada fila debe ser un arreglo que contenga dos elementos:
row_num(primer elemento): el índice basado en cero de la fila de entrada original, que se utiliza para asociar la entrada con la salida. Los valores de row_num deben devolverse en orden ascendente.result (segundo elemento): el valor de una sola fila de salida.
Ejemplo:
{ "results": [ [0, "Beijing"], [1, "Shanghai"], [2, "Shenzhen"], [2, "Guangzhou"] ] }En este ejemplo, la fila de entrada 0 produce una fila de salida, la fila de entrada 1 produce una fila de salida y la fila de entrada 2 produce dos filas de salida. Si una fila de entrada no genera ninguna salida, puede omitir su row_num. Lo único importante es mantener el orden ascendente general.
Ejemplo
Este ejemplo utiliza la función unnest.
-
Active Function Compute.
Inicie sesión en la consola de Function Compute. También puede solicitar un paquete de recursos gratuito siguiendo las indicaciones en pantalla. Para obtener más información, consulte Free Tier.
La primera vez que inicia sesión en la consola de Function Compute, aparece un cuadro de diálogo de autorización de servicio para crear el rol vinculado al servicio
AliyunServiceRoleForFC. Complete la autorización según las indicaciones antes de continuar. -
Cree una función de evento de FC.
En la barra de pestañas superior, seleccione Cloud Functions. Luego, en el panel de navegación izquierdo, haga clic en Functions. Cambie a la región donde reside su instancia de Hologres.
En la página Functions, haga clic en Create Function. En el cuadro de diálogo Choose Your Best-Fit Function Type, mantenga seleccionada la opción Event Function y haga clic en Create Event Function. Se abrirá la página Create Event Function.
-
Configure los siguientes parámetros. Conserve la configuración predeterminada para el resto de los parámetros. Para obtener más información, consulte Create an event-triggered function.
Parámetro
Descripción
Nombre de la función
Un nombre personalizado. Por ejemplo,
unnest.Runtime
Seleccione Built-in Runtimes / Python / Python 3.10.
Método de carga de código
Seleccione Upload ZIP.
Paquete de código
Cargue el paquete de código.
Guarde el siguiente código como unnest.py y comprímalo en un archivo llamado unnest.zip.
import json def unnest(event, context): evt = json.loads(event) data = evt.get('data', None) if data is None: raise ValueError('no "data" key in event.') if not isinstance(data, list): raise ValueError('data is not a list.') res = list() for i in range(len(data)): if not isinstance(data[i], list) or len(data[i]) != 1: raise ValueError('the item in data is not a list.') for item in data[i][0]: res.append([i, item]) return json.dumps({'results': res})NotaComprima el propio archivo
unnest.pypara que quede en la raíz del paquete ZIP. Si el archivo se encuentra dentro de una carpeta, Function Compute no podrá cargar el módulo.Handler
Este campo tiene el valor predeterminado
index.handler. Debe cambiarlo aunnest.unnest.El formato es
<code file name>.<function name>y debe coincidir con el código que cargue. Si deja el valor predeterminado, la llamada a la función remota fallará con el errorImportModuleError: No module named 'index'.
-
Cree una función remota de Hologres.
NotaRealice los siguientes pasos en HoloWeb. Para obtener más información, consulte Connect to HoloWeb.
CREATE EXTENSION IF NOT EXISTS function_compute; CREATE OR REPLACE FUNCTION rf_unnest(INTEGER []) RETURNS SETOF INTEGER LANGUAGE function_compute AS 'xxxxxxxxxxxxxxxxx.cn-shanghai-internal.fc.aliyuncs.com/unnest' STRICT; -
Prepare los datos de prueba.
CREATE TABLE test_array ( numbers INTEGER[] ); INSERT INTO test_array (numbers) VALUES (ARRAY[1, 3]), (ARRAY[2, 4]), ('{}'), (ARRAY[]::INTEGER[]), (NULL); -
Llame a la función remota.
SELECT numbers, rf_unnest(numbers) FROM test_array; numbers | rf_unnest ---------+----------- {2,4} | 2 {2,4} | 4 {1,3} | 1 {1,3} | 3 (4 rows)NotaLlame a la función con el nombre que declaró al crear la función remota (
rf_unnesten este ejemplo), no con el nombre de la función de Function Compute (unnest). Si llama directamente aunnest, se resolverá como la función de arreglos integrada de PostgreSQL con el mismo nombre. Devolverá filas, pero estas no provendrán de Function Compute. Por esta razón se recomienda anteponer el prefijorf_a las funciones remotas.