À partir de la version V3.1, Hologres prend en charge les appels distants vers des fonctions définies par l'utilisateur dans Function Compute (FC) pour traiter une logique métier complexe ou réaliser des opérations de données avancées. Cette rubrique explique comment utiliser les Remote UDFs dans Hologres.
Présentation
Les fonctions distantes étendent les capacités de traitement et d'analyse des données de Hologres en intégrant des fonctions externes issues de services tels qu'Alibaba Cloud Function Compute (FC). Cette intégration vous permet d'appeler dynamiquement des fonctions FC lors de l'interrogation des données Hologres afin de traiter une logique métier complexe ou de réaliser des opérations de données avancées.
Les fonctions distantes couvrent les cas d'utilisation suivants :
Traitement des données en temps réel : appelez des fonctions externes lors des requêtes pour nettoyer les données, convertir des formats ou effectuer des calculs complexes.
Intégration de services tiers : utilisez Function Compute pour interagir avec d'autres services Alibaba Cloud ou des API tierces en exploitant vos données Hologres.
Analyse avancée : utilisez Function Compute pour exécuter des algorithmes d'analyse avancés, tels que l'inférence de modèles et l'apprentissage automatique, puis écrivez les résultats directement dans Hologres.
Prérequis
Vous disposez d'une instance Hologres en version V3.1 ou ultérieure. Pour plus d'informations, consultez la rubrique Achat d'une instance Hologres.
Vous avez activé Function Compute et utilisez une instance V3.0. Pour activer le service, connectez-vous à la console Function Compute.
-
Le rôle lié au service
AliyunServiceRoleForHologresRemoteUDFest autorisé.Connectez-vous à la console Hologres. Dans le volet de navigation de gauche, cliquez sur Create a Service-linked Role.
Dans la boîte de dialogue Create Service-Linked Role, recherchez
AliyunServiceRoleForHologresRemoteUDFet cliquez sur Create Service-linked Role ci-dessous pour finaliser l'autorisation. Si le rôle est déjà autorisé, aucun bouton n'apparaît et aucune action n'est nécessaire.
L'instance Hologres et le service Function Compute doivent se trouver dans la même région.
Activez Alibaba Cloud Function Compute, puis développez et déployez la fonction que Hologres appellera. Pour plus de détails, consultez la rubrique Présentation du développement de code.
Limites
Seules les UDFs scalaires et les fonctions tabulaires définies par l'utilisateur (UDTFs) sont prises en charge. Les fonctions d'agrégat définies par l'utilisateur (UDAFs) ne sont pas prises en charge.
Seuls les types de données suivants et leurs types de tableaux correspondants sont pris en charge :
BOOLEAN,INTEGER,BIGINT,REAL,DOUBLE PRECISIONetTEXT.Les fonctions distantes ne prennent pas en charge les paramètres d'entrée constants.
Cette fonctionnalité engendre des coûts dans Function Compute (FC). Pour plus d'informations, consultez la rubrique Facturation.
Cette fonctionnalité n'engendre aucun coût supplémentaire dans Hologres.
-
Les Remote UDFs s'exécutent uniquement dans le moteur de requête Hologres (HQE). Elles ne peuvent pas coexister dans la même instruction SQL avec des fonctions intégrées exécutées exclusivement dans le moteur de requête compatible PostgreSQL (PQE), telles que les fonctions d'extension de chiffrement et de déchiffrement (PGCRYPTO). Leur utilisation conjointe provoque un conflit d'exécution du moteur et renvoie l'erreur suivante.
ERROR: ORCA failed to produce a plan : No plan has been computed for required propertiesPour utiliser simultanément une Remote UDF et une fonction intégrée exclusive au PQE, séparez les opérations en plusieurs instructions SQL et exécutez-les individuellement.
Gestion des remote UDFs
Création d'une extension
Pour utiliser les fonctions distantes, créez d'abord une extension en exécutant la commande suivante :
CREATE EXTENSION [ IF NOT EXISTS ] function_compute;
Création d'une fonction
Syntaxe
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>
} ...
Paramètres
|
Catégorie |
Paramètre |
Obligatoire |
Description |
|
Nom de la fonction |
function_name |
Oui |
Nom de la fonction.
|
|
Paramètres de la fonction |
argtype |
Oui |
Type de données du paramètre. |
|
argmode |
Non |
Les valeurs valides sont IN, OUT et INOUT. La valeur par défaut est IN. Pour éviter toute ambiguïté, nous vous recommandons de ne pas utiliser INOUT. Une fonction ne peut avoir qu'un seul paramètre OUT ou INOUT. |
|
|
argname |
Non |
Nom du paramètre.
|
|
|
default_expr |
Non |
Valeur par défaut. Cela s'applique uniquement aux paramètres d'entrée. Si un paramètre possède une valeur par défaut, tous les paramètres suivants doivent également avoir des valeurs par défaut. |
|
|
Endpoint FC |
LANGUAGE function_compute |
Oui |
Spécifie que la fonction utilise le service Function Compute. |
|
fc_endpoint |
Oui |
Endpoint interne pour Function Compute. Pour plus d'informations, consultez la rubrique Endpoints. |
|
|
func_name |
Oui |
Nom de la fonction cible, qui doit être créé au préalable dans la console Function Compute. |
|
|
Type de retour |
rettype |
Non |
Type de données de la valeur de retour. Si vous utilisez des paramètres OUT ou INOUT, vous pouvez omettre la clause RETURNS. Si elle est spécifiée, cette clause doit être cohérente avec le type de résultat implicite des paramètres de sortie. |
|
column_name |
Non |
Dans la syntaxe RETURNS TABLE, il s'agit du nom d'une colonne de sortie. C'est une autre façon de déclarer des paramètres OUT nommés. La différence est que RETURNS TABLE implique également RETURNS SETOF, ce qui signifie que la fonction renvoie un ensemble. |
|
|
column_type |
Non |
Dans la syntaxe RETURNS TABLE, il s'agit du type de données d'une colonne de sortie. |
|
|
Politique de gestion des valeurs NULL |
CALLED ON NULL INPUT |
Non |
Comportement par défaut. La fonction est appelée même pour les entrées NULL et doit gérer elle-même la logique NULL. |
|
RETURNS NULL ON NULL INPUT |
Non |
Renvoie immédiatement NULL si une entrée est NULL. |
|
|
STRICT |
Non |
Alias de RETURNS NULL ON NULL INPUT. |
|
|
Contrôle de version de la fonction |
qualifier |
Non |
Spécifie la version ou l'alias de la fonction à appeler. La valeur par défaut est |
|
Algorithme de compression des requêtes |
compression |
Non |
Spécifie l'algorithme de compression pour la requête et la réponse d'appel de fonction. Valeurs valides :
|
|
Taille maximale du lot par requête |
max_batch_size |
Non |
Spécifie le nombre maximal de lignes à envoyer à FC dans chaque lot. Utilisez ce paramètre pour limiter la taille du lot pour les fonctions FC soumises à des limites de mémoire ou d'autres contraintes. Si vous ne spécifiez pas ce paramètre, Hologres calcule et utilise automatiquement la taille de lot optimale. Dans la plupart des cas, vous n'avez pas besoin de définir ce paramètre. |
Exemples
Dans les exemples suivants, add et unnest sont des noms de fonctions dans Function Compute, tandis que rf_add et rf_unnest sont les noms de fonctions enregistrés dans Hologres. Avant d'exécuter ces instructions, créez les fonctions correspondantes dans Function Compute et remplacez l'endpoint interne et le nom de la fonction dans la clause AS par vos propres valeurs. Pour connaître les formats de requête et de réponse que votre fonction doit implémenter, consultez la rubrique Format d'échange de données.
-
Créez une UDF scalaire.
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' ; -
Créez une 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;
Consultation des fonctions
Consultez les fonctions distantes créées.
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;
Suppression d'une fonction
Syntaxe
DROP FUNCTION [ IF EXISTS ] <function_name> [ ( [ [ argmode ] [ argname ] <argtype> [, ...] ] ) ] [, ...]
Paramètres
|**Paramètre**
|
**Obligatoire**
|
**Description**
| | --- | --- | --- | |
function_name
|
Oui
|
Nom de la fonction à supprimer.
| |
argtype
|
Oui
|
Type de données du paramètre.
| |
argmode
|
Non
|
Les valeurs valides sont IN, OUT et INOUT. La valeur par défaut est IN. Pour éviter toute ambiguïté, nous vous recommandons de ne pas utiliser INOUT. Une fonction ne peut avoir qu'un seul paramètre OUT ou INOUT.
| |
argname
|
Non
|
Nom du paramètre. Pour les paramètres d'entrée, le nom sert uniquement à des fins de documentation. Pour les paramètres de sortie, le nom détermine le nom de la colonne dans l'ensemble de résultats. S'il est omis, le système génère un nom par défaut.
|
Exemple
DROP FUNCTION rf_add(INTEGER, INTEGER);
Format d'échange de données
Format de requête : de Hologres vers FC
Hologres appelle l'API InvokeFunction de Function Compute en envoyant une requête POST. Le corps de la requête est un objet JSON. Cet objet contient une seule clé nommée data. Sa valeur est un tableau bidimensionnel, où chaque tableau interne représente une ligne de données dans le lot et contient les paramètres pour l'appel de fonction.
Règles de sérialisation des données
BOOLEANest sérialisé en un booléen JSON.INTEGERetBIGINTsont sérialisés en un nombre JSON.REALetDOUBLE PRECISIONsont sérialisés en un nombre JSON.TEXTest sérialisé en une chaîne JSON.Une valeur SQL
NULLest sérialisée ennullJSON.
Exemple
Le code suivant montre un exemple de requête sérialisée pour une fonction distante avec la signature rf_demo(TEXT, INTEGER, BOOLEAN).
{
"data": [
["foo", 100, true],
[null, null, false],
["bar", 200, false]
]
}
Format de réponse : de FC vers Hologres
Après avoir traité un lot de données, Function Compute doit renvoyer les résultats à Hologres au format JSON comme suit :
-
UDF scalaire
L'objet de niveau supérieur doit contenir un champ
results. Sa valeur doit être un tableau, où chaque élément correspond au résultat pour une ligne de données d'entrée.Chaque résultat de ligne doit être un tableau, et l'ordre des résultats doit correspondre à l'ordre des lignes d'entrée. Par exemple, le Nième élément du tableau de résultats correspond à la Nième ligne d'entrée.
Le code suivant montre un exemple de réponse pour un lot de quatre lignes :
{ "results": [ ["Beijing"], ["Shanghai"], ["Shenzhen"], ["Guangzhou"] ] } -
Une fonction tabulaire définie par l'utilisateur (UDTF) prend en charge l'entrée d'une seule ligne pour générer plusieurs lignes de sortie. Un numéro de ligne (row_num) est requis pour identifier la relation avec la ligne d'entrée d'origine.
L'objet de niveau supérieur doit contenir un champ
results. Sa valeur doit être un tableau, où chaque élément correspond à une ligne de données de sortie.-
Chaque résultat de ligne doit être un tableau contenant deux éléments :
row_num(premier élément) : index de base zéro de la ligne d'entrée d'origine, utilisé pour associer l'entrée à la sortie. Les valeurs row_num doivent être renvoyées par ordre croissant.résultat (deuxième élément) : valeur d'une seule ligne de sortie.
Exemple :
{ "results": [ [0, "Beijing"], [1, "Shanghai"], [2, "Shenzhen"], [2, "Guangzhou"] ] }Dans cet exemple, la ligne d'entrée 0 produit une ligne de sortie, la ligne d'entrée 1 produit une ligne de sortie et la ligne d'entrée 2 produit deux lignes de sortie. Si une ligne d'entrée ne produit aucune sortie, vous pouvez omettre son row_num. Seul l'ordre croissant global importe.
Exemple
Cet exemple utilise la fonction unnest.
-
Activez Function Compute.
Connectez-vous à la console Function Compute. Vous pouvez également réclamer un forfait de ressources gratuit en suivant les instructions à l'écran. Pour plus d'informations, consultez la rubrique Offre gratuite.
La première fois que vous vous connectez à la console Function Compute, une boîte de dialogue d'autorisation de service apparaît pour créer le rôle lié au service
AliyunServiceRoleForFC. Effectuez l'autorisation comme indiqué avant de continuer. -
Créez une fonction d'événement FC.
Dans la barre d'onglets supérieure, sélectionnez Cloud Functions. Ensuite, dans le volet de navigation de gauche, cliquez sur Functions. Basculez vers la région où réside votre instance Hologres.
Sur la page Functions, cliquez sur Create Function. Dans la boîte de dialogue Choose Your Best-Fit Function Type, conservez Event Function sélectionné et cliquez sur Create Event Function. La page Create Event Function s'ouvre.
-
Configurez les paramètres suivants. Conservez les paramètres par défaut pour les autres paramètres. Pour plus d'informations, consultez la rubrique Création d'une fonction déclenchée par un événement.
Paramètre
Description
Nom de la fonction
Un nom personnalisé. Par exemple,
unnest.Runtime
Sélectionnez Built-in Runtimes / Python / Python 3.10.
Méthode de téléchargement du code
Sélectionnez Upload ZIP.
Package de code
Téléchargez le package de code.
Enregistrez le code suivant sous le nom unnest.py et compressez-le dans un fichier nommé 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})RemarqueCompressez le fichier
unnest.pylui-même afin queunnest.pyse trouve à la racine du package ZIP. Si le fichier est imbriqué dans un dossier, Function Compute ne peut pas charger le module.Handler
Ce champ a par défaut la valeur
index.handler. Vous devez la modifier enunnest.unnest.Le format est
<nom du fichier de code>.<nom de la fonction>et doit correspondre au code que vous téléchargez. Si vous laissez la valeur par défaut, l'appel de la fonction distante échoue avec l'erreurImportModuleError: No module named 'index'.
-
Créez une fonction distante Hologres.
RemarqueEffectuez les étapes suivantes dans HoloWeb. Pour plus d'informations, consultez la rubrique Connexion à 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; -
Préparez les données de test.
CREATE TABLE test_array ( numbers INTEGER[] ); INSERT INTO test_array (numbers) VALUES (ARRAY[1, 3]), (ARRAY[2, 4]), ('{}'), (ARRAY[]::INTEGER[]), (NULL); -
Appelez la fonction distante.
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)RemarqueAppelez la fonction par le nom que vous avez déclaré lors de la création de la fonction distante (
rf_unnestdans cet exemple), et non par le nom de la fonction Function Compute (unnest). L'appel direct deunnestrésout la fonction intégrée PostgreSQL de tableau portant le même nom. Elle renvoie des lignes, mais ces lignes ne proviennent pas de Function Compute. C'est pourquoi nous vous recommandons de préfixer les fonctions distantes parrf_.