Implementare i controlli dei tipi di dati
Ogni colonna del set di dati ha un tipo di dati previsto e quando i dati in ingresso non corrispondono a tale aspettativa, i problemi si verificano a catena, influenzando i processi successivi. Un valore stringa al posto di un numero intero può interrompere i calcoli, corrompere le aggregazioni o causare errori nella pipeline. I controlli del tipo di dati assicurano che ogni campo contenga valori del tipo corretto prima di immettere le tabelle.
In questa unità si apprenderà come implementare controlli dei tipi di dati usando l'imposizione dello schema, il cast esplicito dei tipi e i vincoli di convalida in Azure Databricks.
Comprendere l'applicazione dello schema
Delta Lake convalida automaticamente i tipi di dati quando si scrivono dati in una tabella. Questo meccanismo predefinito, denominato imposizione dello schema, confronta i tipi di dati delle colonne in ingresso rispetto allo schema della tabella di destinazione. Quando si verifica un'incompatibilità di tipo, Delta Lake tenta di effettuare un cast sicuro del valore. Se il cast ha esito negativo, l'operazione di scrittura genera un errore.
L'applicazione dello schema applica le regole seguenti durante le operazioni di inserimento:
- Tutte le colonne inserite devono esistere nella tabella di destinazione
- Tutti i tipi di dati delle colonne devono corrispondere o essere castabili in modo sicuro ai tipi di destinazione
Si consideri una tabella con una colonna integer:
CREATE TABLE inventory (
product_id INT,
quantity INT,
last_updated DATE
);
Quando si inseriscono dati in cui quantity è una stringa che rappresenta un numero, Delta Lake esegue il cast al tipo di destinazione:
-- This succeeds because '100' can be cast to INT
INSERT INTO inventory VALUES (1, '100', '2026-01-15');
Tuttavia, l'inserimento di una stringa che non può essere convertita in un numero intero causa l'esito negativo dell'operazione:
-- This fails because 'fifty' cannot be cast to INT
INSERT INTO inventory VALUES (2, 'fifty', '2026-01-15');
L'applicazione dello schema fornisce una prima linea di difesa contro i disallineamenti di tipo. Per un maggiore controllo sulla modalità di gestione delle mancate corrispondenze, è possibile usare il cast esplicito.
Usare il cast esplicito dei tipi
La cast funzione converte i valori da un tipo di dati a un altro. Quando la conversione non riesce, viene generato un errore. La try_cast funzione funziona allo stesso modo, ma restituisce NULL invece di generare un errore quando la conversione non riesce.
Usare cast quando si vuole una convalida rigorosa che arresta l'elaborazione su dati non validi:
SELECT
cast(raw_amount AS DECIMAL(10,2)) AS amount,
cast(raw_date AS DATE) AS transaction_date
FROM staging_data;
Usare try_cast quando si vogliono identificare valori non validi senza far fallire la query.
SELECT
raw_amount,
try_cast(raw_amount AS DECIMAL(10,2)) AS validated_amount,
CASE
WHEN try_cast(raw_amount AS DECIMAL(10,2)) IS NULL
THEN 'Invalid amount format'
ELSE 'Valid'
END AS validation_status
FROM staging_data;
Con try_cast, i record con valori non validi restituiscono NULL per la colonna cast. È quindi possibile filtrare, contrassegnare o mettere in quarantena questi record in base ai requisiti di qualità dei dati.
Implementare la convalida dei tipi con vincoli
I vincoli CHECK consentono di definire regole di convalida personalizzate applicate ogni volta che i dati vengono inseriti o aggiornati. Anche se in genere viene usato per intervalli di valori e modelli, è possibile combinarli con funzioni in grado di riconoscimento dei tipi per creare controlli di tipo sofisticati.
Ad esempio, è possibile verificare che una colonna stringa contenga solo caratteri numerici:
CREATE TABLE orders (
order_id INT,
order_total STRING
);
ALTER TABLE orders
ADD CONSTRAINT valid_order_total CHECK (order_total REGEXP '^[0-9]+(\\.[0-9]+)?$')
Questo vincolo garantisce che la order_total colonna contenga valori simili a numeri validi, rilevando dati in formato non valido prima che entrino nella tabella.
Per la convalida della data, è possibile usare la try_cast funzione all'interno di un vincolo:
ALTER TABLE events
ADD CONSTRAINT valid_event_date CHECK (try_cast(event_date_str AS DATE) IS NOT NULL);
Questo approccio rifiuta i record in cui event_date_str non contiene un formato di data valido.
Importante
Prima di aggiungere un vincolo a una tabella esistente, Azure Databricks verifica che tutte le righe esistenti soddisfino il vincolo. Pianificare questo passaggio di convalida, in particolare nelle tabelle di grandi dimensioni.
Gestire le mancate corrispondenze dei tipi nelle pipeline
Quando si elaborano dati provenienti da fonti esterne, i disallineamenti di tipo sono comuni. Implementare un modello che separa i record validi dai record non validi, consentendo di elaborare dati validi durante la quarantena dei record problematici per la revisione:
-- Insert valid records into the target table
INSERT INTO silver_transactions
SELECT
transaction_id,
cast(amount AS DECIMAL(10,2)) AS amount,
cast(transaction_date AS DATE) AS transaction_date
FROM bronze_transactions
WHERE try_cast(amount AS DECIMAL(10,2)) IS NOT NULL
AND try_cast(transaction_date AS DATE) IS NOT NULL;
-- Capture invalid records for investigation
INSERT INTO quarantine_transactions
SELECT
transaction_id,
amount AS raw_amount,
transaction_date AS raw_date,
current_timestamp() AS quarantined_at,
'Type validation failed' AS reason
FROM bronze_transactions
WHERE try_cast(amount AS DECIMAL(10,2)) IS NULL
OR try_cast(transaction_date AS DATE) IS NULL;
Questo modello garantisce che la pipeline continui a elaborare dati validi mantenendo record non validi per un'analisi successiva.
Usare le aspettative del flusso per la verifica dei tipi
Le pipeline di Lakeflow offrono expectations che consentono di definire regole di qualità dei dati direttamente nelle definizioni della pipeline. È possibile usare le aspettative per verificare che sia possibile eseguire il cast dei valori ai tipi previsti:
from pyspark import pipelines as dp
@dp.table
@dp.expect_or_drop("valid_amount", "try_cast(amount AS DECIMAL(10,2)) IS NOT NULL")
@dp.expect_or_drop("valid_date", "try_cast(event_date AS DATE) IS NOT NULL")
def validated_transactions():
return spark.readStream.table("raw_transactions")
Con expect_or_drop, i record che non soddisfano il controllo del tipo vengono eliminati prima di raggiungere la tabella di destinazione. Usare expect per registrare le violazioni senza eliminare i record o expect_or_fail arrestare la pipeline quando si verificano violazioni.
Per le pipeline basate su SQL:
CREATE OR REFRESH STREAMING TABLE validated_transactions (
CONSTRAINT valid_amount EXPECT (try_cast(amount AS DECIMAL(10,2)) IS NOT NULL) ON VIOLATION DROP ROW,
CONSTRAINT valid_date EXPECT (try_cast(event_date AS DATE) IS NOT NULL) ON VIOLATION DROP ROW
)
AS SELECT * FROM STREAM(raw_transactions);
Le aspettative della pipeline integrano la convalida dei tipi di dati direttamente nella logica ETL, offrendo visibilità sulle metriche relative alla qualità dei dati tramite l'interfaccia utente della pipeline.
L'implementazione dei controlli dei tipi di dati a più livelli, ovvero l'imposizione dello schema, il cast esplicito, i vincoli e le aspettative della pipeline, crea una difesa approfondita. Ogni livello rileva problemi che potrebbero scivolare oltre gli altri, con conseguente maggiore qualità dei dati nelle tabelle del catalogo Unity.