Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
CREATE EXTERNAL FUNCTION
Crea una funzione scalare definita dall'utente (UDF) basata su Amazon AWS Lambda Redshift. Per ulteriori informazioni sulle funzioni Lambda definite dall'utente, consultare Lambda scalare UDFs.
Privilegi richiesti
Di seguito sono riportati i privilegi richiesti per: CREATE EXTERNAL FUNCTION
Superuser
Utenti con il CREATE privilegio [ORREPLACE] EXTERNAL FUNCTION
Sintassi
CREATE [ OR REPLACE ] EXTERNAL FUNCTION external_fn_name ( [data_type] [, ...] ) RETURNS data_type { VOLATILE | STABLE } LAMBDA 'lambda_fn_name' IAM_ROLE { default | ‘arn:aws:iam::
<Account AWS-id>
:role/<role-name>
’ RETRY_TIMEOUT milliseconds MAX_BATCH_ROWS count MAX_BATCH_SIZE size [ KB | MB ];
Parametri
- OPPURE REPLACE
-
Una clausola che specifica che se una funzione con stesso nome e tipi di dati degli argomenti di input o firma è già esistente, la funzione esistente viene sostituita. Puoi sostituire una funzione solo con una nuova funzione che definisce un set identico di tipi di dati. Devi essere un utente con privilegi avanzati per sostituire una funzione.
Se definisci una funzione con lo stesso nome di una funzione esistente ma con una firma diversa, viene creata una nuova funzione. In altre parole, il nome della funzione è sottoposto a overload. Per ulteriori informazioni, consulta Overload dei nomi delle funzioni.
- external_fn_name
-
Il nome della funzione esterna. Se si specifica un nome schema (come myschema.myfunction), la funzione viene creata utilizzando lo schema specificato. Altrimenti, la funzione viene creata nello schema corrente. Per ulteriori informazioni sui nomi validi, consultare Nomi e identificatori.
Si consiglia di inserire come prefisso tutti i UDF nomi con
f_
. Amazon Redshift riserva ilf_
prefisso per i nomi. UDF Utilizzando ilf_
prefisso, contribuisci a garantire che il tuo UDF nome non entri in conflitto con i nomi delle SQL funzioni integrate di Amazon Redshift ora o in futuro. Per ulteriori informazioni, consulta Prevenzione dei conflitti UDF di denominazione. - data_type
-
Il tipo di dati per gli argomenti di input. Per ulteriori informazioni, consulta Tipi di dati.
- RETURNStipo_dati
-
Il tipo di dati del valore restituito dalla funzione. Il tipo di RETURNS dati può essere qualsiasi tipo di dati Amazon Redshift standard. Per ulteriori informazioni, consulta Tipi di dati Python UDF.
- VOLATILE | STABLE
-
Informa l'ottimizzatore di query circa la volatilità della funzione.
Per ottenere la migliore ottimizzazione, etichettare la funzione con la categoria di volatilità più rigida valida. In ordine di rigidità, a partire dalla meno rigida, le categorie di volatilità sono le seguenti:
-
VOLATILE
-
STABLE
VOLATILE
Dati gli stessi argomenti, la funzione può restituire risultati diversi su chiamate successive, anche per le righe in una singola istruzione. L'ottimizzatore di query non può fare alcuna ipotesi sul comportamento di una funzione volatile. Una query che utilizza una funzione volatile deve rivalutare la funzione per ogni input.
STABLE
Dati gli stessi argomenti, la funzione è garantita per restituire gli stessi risultati nelle chiamate successive elaborate all'interno di una singola istruzione. La funzione può restituire risultati diversi se richiamati in istruzioni diverse. Questa categoria consente all'ottimizzatore di ridurre il numero di volte in cui la funzione viene chiamata all'interno di una singola istruzione.
Nota che se la severità scelta non è valida per la funzione, c'è il rischio che l'ottimizzatore salti alcune chiamate in base a questa severità. Ciò può comportare un set di risultati errato.
La IMMUTABLE clausola non è attualmente supportata per LambdaUDFs.
-
- LAMBDA'lambda_fn_name'
-
Il nome della funzione richiamata da Amazon Redshift.
Per i passaggi per creare una AWS Lambda funzione, consulta Creare una funzione Lambda con la console nella Guida per gli AWS Lambda sviluppatori.
Per informazioni sulle autorizzazioni richieste per la funzione Lambda, consultare Autorizzazioni AWS Lambda nella Guida per gli sviluppatori di AWS Lambda .
- IAM_ ROLE {default | 'arn:aws:iam::
<Account AWS-id>
:ruolo/<role-name>
’ -
Utilizza la parola chiave predefinita per fare in modo che Amazon Redshift utilizzi il IAM ruolo impostato come predefinito e associato al cluster durante l'esecuzione del CREATE EXTERNAL FUNCTION comando.
Usa Amazon Resource Name (ARN) per un IAM ruolo utilizzato dal tuo cluster per l'autenticazione e l'autorizzazione. Il CREATE EXTERNAL FUNCTION comando è autorizzato a richiamare le funzioni Lambda tramite IAM questo ruolo. Se il tuo cluster ha un IAM ruolo esistente con autorizzazioni per richiamare le funzioni Lambda allegate, puoi sostituirlo con quello del tuo. ARN Per ulteriori informazioni, consulta Configurazione del parametro di autorizzazione per Lambda UDFs.
Di seguito viene illustrata la sintassi del parametro _. IAM ROLE
IAM_ROLE 'arn:aws:iam::aws-account-id:role/role-name'
- RETRY_ TIMEOUT millisecondi
-
La quantità di tempo totale, espressa in millisecondi, utilizzata da Amazon Redshift per i ritardi nei backoff dei tentativi.
Invece di riprovare immediatamente per eventuali query non riuscite, Amazon Redshift esegue i backoff e attende un certo periodo di tempo tra i tentativi. Quindi Amazon Redshift ritenta la richiesta per eseguire nuovamente la query non riuscita finché la somma di tutti i ritardi non è uguale o superiore al valore _ specificato. RETRY TIMEOUT Il valore di default è 20.000 millisecondi.
Quando viene richiamata una funzione Lambda, Amazon Redshift prova a eseguire nuovamente le query che ricevono errori come
TooManyRequestsException
,EC2ThrottledException
eServiceException
.È possibile impostare il TIMEOUT parametro RETRY _ su 0 millisecondi per impedire eventuali nuovi tentativi per una Lambda. UDF
- MAX_ _ conta BATCH ROWS
-
Numero massimo di righe che Amazon Redshift invia in una singola richiesta batch per una singola chiamata lambda.
Il valore minimo per questo parametro è 1. Il valore massimo è INT _MAX, ovvero 2.147.483.647.
Questo parametro è facoltativo. Il valore predefinito è _, ovvero 2.147.483.647. INT MAX
- MAX_ BATCH _ dimensione [KB | MB] SIZE
-
La dimensione massima del payload di dati che Amazon Redshift invia in una singola richiesta batch per una singola chiamata lambda.
Il valore minimo per questo parametro è 1 KB. Il valore massimo è 5 MB.
Il valore predefinito di questo parametro è 5 MB.
KB e MB sono facoltativi. Se non si imposta l'unità di misura, Amazon Redshift utilizza per impostazione predefinita KB.
Note per l'utilizzo
Considera quanto segue quando crei UDFs Lambda:
L'ordine delle chiamate alla funzione Lambda sugli argomenti di input non è fisso o garantito. Può variare tra le istanze di esecuzione delle query, a seconda della configurazione del cluster.
Non è garantito che le funzioni vengano applicate a ciascun argomento di input una sola volta. L'interazione tra Amazon Redshift e AWS Lambda potrebbe portare a chiamate ripetitive con gli stessi input.
Esempi
Di seguito sono riportati alcuni esempi di utilizzo delle funzioni scalari definite dall'utente Lambda (). UDFs
Esempio di UDF Lambda scalare con una funzione Lambda Node.js
L'esempio seguente crea una funzione esterna denominata exfunc_sum
che utilizza due numeri interi come argomenti di input. Questa funzione restituisce la somma come output intero. Il nome della funzione Lambda da chiamare è lambda_sum
. La lingua utilizzata per questa funzione Lambda è Node.js 12.x. Assicurati di specificare il ruolo. IAM L'esempio utilizza 'arn:aws:iam::123456789012:user/johndoe'
come IAM ruolo.
CREATE EXTERNAL FUNCTION exfunc_sum(INT,INT) RETURNS INT VOLATILE LAMBDA 'lambda_sum' IAM_ROLE 'arn:aws:iam::123456789012:role/Redshift-Exfunc-Test';
La funzione Lambda accetta il payload della richiesta ed esegue l'iterazione su ogni riga. Tutti i valori di una singola riga vengono aggiunti per calcolare la somma per quella riga, che viene salvata nell'array di risposte. Il numero di righe nell'array dei risultati è simile al numero di righe ricevute nel payload della richiesta.
Il payload di JSON risposta deve contenere i dati dei risultati nel campo «risultati» per essere riconosciuto dalla funzione esterna. Il campo argomenti nella richiesta inviata alla funzione Lambda contiene il payload dei dati. In caso di richiesta batch, è possibile avere più righe nel payload dei dati. La seguente funzione Lambda itera su tutte le righe nel payload dei dati della richiesta. Inoltre, itera individualmente su tutti i valori all'interno di una singola riga.
exports.handler = async (event) => { // The 'arguments' field in the request sent to the Lambda function contains the data payload. var t1 = event['arguments']; // 'len(t1)' represents the number of rows in the request payload. // The number of results in the response payload should be the same as the number of rows received. const resp = new Array(t1.length); // Iterating over all the rows in the request payload. for (const [i, x] of t1.entries()) { var sum = 0; // Iterating over all the values in a single row. for (const y of x) { sum = sum + y; } resp[i] = sum; } // The 'results' field should contain the results of the lambda call. const response = { results: resp }; return JSON.stringify(response); };
Nell'esempio seguente viene chiamata la funzione esterna con valori letterali.
select exfunc_sum(1,2); exfunc_sum ------------ 3 (1 row)
Nell'esempio seguente viene creata una tabella denominata t_sum con due colonne, c1 e c2, del tipo di dati intero e vengono inserite due righe di dati. Quindi la funzione esterna viene chiamata passando i nomi delle colonne di questa tabella. Le due righe della tabella vengono inviate in una richiesta batch nel payload della richiesta come un singolo richiamo Lambda.
CREATE TABLE t_sum(c1 int, c2 int); INSERT INTO t_sum VALUES (4,5), (6,7); SELECT exfunc_sum(c1,c2) FROM t_sum; exfunc_sum --------------- 9 13 (2 rows)
Esempio scalare di UDF Lambda con l'RETRYattributo _ TIMEOUT
Nella sezione seguente, puoi trovare un esempio di come utilizzare l'TIMEOUTattributo RETRY _ in UDFs Lambda.
AWS Lambda le funzioni hanno limiti di concorrenza che è possibile impostare per ogni funzione. Per ulteriori informazioni sui limiti di concorrenza, consulta Gestire la concorrenza per una funzione Lambda nella Guida per gli AWS Lambda sviluppatori e il post Managing AWS Lambda Function Concurrency
Quando il numero di richieste servite da una Lambda UDF supera i limiti di concorrenza, le nuove richieste ricevono l'errore. TooManyRequestsException
Lambda UDF riprova a risolvere questo errore finché la somma di tutti i ritardi tra le richieste inviate alla funzione Lambda è uguale o superiore al valore _ impostato. RETRY TIMEOUT Il valore RETRY _ predefinito è 20.000 TIMEOUT millisecondi.
L'esempio seguente crea una funzione Lambda denominata exfunc_sleep_3
. Questa funzione prende in carico il payload della richiesta, itera su ogni riga e converte l'input in maiuscolo. Quindi si interrompe per 3 secondi e restituisce il risultato. Il linguaggio utilizzato per questa funzione Lambda è Python 3.8.
Il numero di righe nell'array dei risultati è simile al numero di righe ricevute nel payload della richiesta. Il payload di JSON risposta deve contenere i dati dei risultati nel results
campo per essere riconosciuto dalla funzione esterna. Il campo arguments
nella richiesta inviata alla funzione Lambda contiene il payload dei dati. In caso di richiesta batch, è possibile avere più righe nel payload dei dati.
Il limite di concorrenza per questa funzione è specificamente impostato su 1 nella concorrenza riservata per dimostrare l'uso dell'RETRYattributo _. TIMEOUT Quando l'attributo è impostato su 1, la funzione Lambda può servire solo una richiesta alla volta.
import json import time def lambda_handler(event, context): t1 = event['arguments'] # 'len(t1)' represents the number of rows in the request payload. # The number of results in the response payload should be the same as the number of rows received. resp = [None]*len(t1) # Iterating over all rows in the request payload. for i, x in enumerate(t1): # Iterating over all the values in a single row. for j, y in enumerate(x): resp[i] = y.upper() time.sleep(3) ret = dict() ret['results'] = resp ret_json = json.dumps(ret) return ret_json
Di seguito, due esempi aggiuntivi illustrano l'RETRYattributo _. TIMEOUT Ciascuno di essi invoca una singola LambdaUDF. Durante l'invocazione di UDF Lambda, ogni esempio esegue la SQL stessa query per richiamare la UDF Lambda da due sessioni di database simultanee contemporaneamente. Quando la prima query che richiama la Lambda UDF viene servita daUDF, la seconda riceve l'errore. TooManyRequestsException
Questo risultato si verifica perché hai impostato specificamente la concorrenza riservata su 1. UDF Per informazioni su come configurare la simultaneità riservata per le funzioni Lambda, consultare Configurazione della simultaneità riservata.
Il primo esempio, che segue, imposta l'TIMEOUTattributo RETRY _ per Lambda su 0 UDF millisecondi. Se la richiesta Lambda riceve una qualsiasi eccezione dalla funzione Lambda, Amazon Redshift non esegue alcun nuovo tentativo. Questo risultato si verifica perché l'TIMEOUTattributo RETRY _ è impostato su 0.
CREATE OR REPLACE EXTERNAL FUNCTION exfunc_upper(varchar) RETURNS varchar VOLATILE LAMBDA 'exfunc_sleep_3' IAM_ROLE 'arn:aws:iam::123456789012:role/Redshift-Exfunc-Test' RETRY_TIMEOUT 0;
Con RETRY _ TIMEOUT impostato su 0, è possibile eseguire le due query seguenti da sessioni di database separate per visualizzare risultati diversi.
La prima SQL query che utilizza Lambda UDF viene eseguita correttamente.
select exfunc_upper('Varchar'); exfunc_upper -------------- VARCHAR (1 row)
La seconda query, eseguita contemporaneamente da una sessione di database separata, riceve l'errore TooManyRequestsException
.
select exfunc_upper('Varchar'); ERROR: Rate Exceeded.; Exception: TooManyRequestsException; ShouldRetry: 1 DETAIL: ----------------------------------------------- error: Rate Exceeded.; Exception: TooManyRequestsException; ShouldRetry: 1 code: 32103 context:query: 0 location: exfunc_client.cpp:102 process: padbmaster [pid=26384] -----------------------------------------------
Il secondo esempio, che segue, imposta l'TIMEOUTattributo RETRY _ per Lambda su 3.000 UDF millisecondi. Anche se la seconda query viene eseguita contemporaneamente, la UDF Lambda riprova finché i ritardi totali non raggiungono i 3.000 millisecondi. Pertanto, entrambe le query vengono eseguite correttamente.
CREATE OR REPLACE EXTERNAL FUNCTION exfunc_upper(varchar) RETURNS varchar VOLATILE LAMBDA 'exfunc_sleep_3' IAM_ROLE 'arn:aws:iam::123456789012:role/Redshift-Exfunc-Test' RETRY_TIMEOUT 3000;
Con RETRY _ TIMEOUT impostato su 3.000 millisecondi, puoi eseguire le due query seguenti da sessioni di database separate per ottenere gli stessi risultati.
La prima SQL query che esegue Lambda viene UDF eseguita correttamente.
select exfunc_upper('Varchar'); exfunc_upper -------------- VARCHAR (1 row)
La seconda query viene eseguita contemporaneamente e UDF Lambda riprova fino a quando il ritardo totale è di 3.000 millisecondi.
select exfunc_upper('Varchar'); exfunc_upper -------------- VARCHAR (1 row)
Esempio scalare di UDF Lambda utilizzando una funzione Lambda in Python
L'esempio seguente crea una funzione esterna denominata exfunc_multiplication
e che moltiplica i numeri e restituisce un numero intero. Questo esempio incorpora il successo e i campi error_msg
nella risposta Lambda. Il campo di successo è impostato su false quando c'è un overflow di numeri interi nel risultato della moltiplicazione e il messaggio error_msg
è impostato su Integer multiplication overflow
. La funzione exfunc_multiplication
accetta tre numeri interi come argomenti di input e restituisce la somma come output intero.
Il nome della funzione Lambda richiamata è lambda_multiplication
. Il linguaggio utilizzato per questa funzione Lambda è Python 3.8. Assicurati di specificare il ruolo. IAM
CREATE EXTERNAL FUNCTION exfunc_multiplication(int, int, int) RETURNS INT VOLATILE LAMBDA 'lambda_multiplication' IAM_ROLE 'arn:aws:iam::123456789012:role/Redshift-Exfunc-Test';
La funzione Lambda accetta il payload della richiesta ed esegue l'iterazione su ogni riga. Tutti i valori di una singola riga vengono moltiplicati per calcolare il risultato di tale riga, che viene salvato nell'elenco delle risposte. In questo esempio viene utilizzato un valore di successo booleano impostato su true per impostazione predefinita. Se il risultato della moltiplicazione per una riga ha un overflow intero, il valore di successo è impostato su false. Quindi il ciclo di iterazione si interrompe.
Durante la creazione del payload di risposta, se il valore di successo è false, la seguente funzione Lambda aggiunge il campo error_msg
nel payload. Imposta anche il messaggio di errore su Integer multiplication overflow
. Se il valore di successo è true, i dati dei risultati vengono aggiunti nel campo dei risultati. Il numero di righe nell'array dei risultati, se presente, è simile al numero di righe ricevute nel payload della richiesta.
Il campo argomenti nella richiesta inviata alla funzione Lambda contiene il payload dei dati. In caso di richiesta batch, è possibile avere più righe nel payload dei dati. La seguente funzione Lambda itera su tutte le righe nel payload dei dati richiesta e itera individualmente su tutti i valori all'interno di una singola riga.
import json def lambda_handler(event, context): t1 = event['arguments'] # 'len(t1)' represents the number of rows in the request payload. # The number of results in the response payload should be the same as the number of rows received. resp = [None]*len(t1) # By default success is set to 'True'. success = True # Iterating over all rows in the request payload. for i, x in enumerate(t1): mul = 1 # Iterating over all the values in a single row. for j, y in enumerate(x): mul = mul*y # Check integer overflow. if (mul >= 9223372036854775807 or mul <= -9223372036854775808): success = False break else: resp[i] = mul ret = dict() ret['success'] = success if not success: ret['error_msg'] = "Integer multiplication overflow" else: ret['results'] = resp ret_json = json.dumps(ret) return ret_json
Nell'esempio seguente viene chiamata la funzione esterna con valori letterali.
SELECT exfunc_multiplication(8, 9, 2); exfunc_multiplication --------------------------- 144 (1 row)
Nell'esempio seguente viene creata una tabella denominata t_multi con tre colonne, c1, c2 e c3, del tipo di dati intero. La funzione esterna viene chiamata passando i nomi delle colonne di questa tabella. I dati vengono inseriti in modo tale da causare l'overflow di interi per mostrare come l'errore viene propagato.
CREATE TABLE t_multi (c1 int, c2 int, c3 int); INSERT INTO t_multi VALUES (2147483647, 2147483647, 4); SELECT exfunc_multiplication(c1, c2, c3) FROM t_multi; DETAIL: ----------------------------------------------- error: Integer multiplication overflow code: 32004context: context: query: 38 location: exfunc_data.cpp:276 process: query2_16_38 [pid=30494] -----------------------------------------------