Chi lavora con dati clinici prima o poi incontra HL7. È un formato ASCII che ospedali, laboratori e assicurazioni usano per scambiarsi informazioni su pazienti, ricoveri, farmaci somministrati e interventi eseguiti. Un singolo documento può contenere tutti questi oggetti insieme, ed è qui che iniziano i problemi per chi deve costruire una pipeline di ingestion.
Perché HL7 rompe il parsing standard
Un post di Fivetran, firmato dal partner sales engineer David Millman, lo confronta con EDI, formato già trattato nella stessa serie. Le differenze pratiche sono due. La prima è cosmetica: HL7 usa la pipe come field delimiter al posto dell’asterisco. La seconda pesa molto di più: manca un record delimiter, mentre in EDI quel ruolo era svolto dalla tilde. In più i record possono essere nested, quindi un solo giro di parsing non basta: serve un secondo passaggio sui sub-field, separati dal carattere caret.
L’approccio: caricare grezzo, parsare in SQL
La ricetta descritta è deliberatamente poco sofisticata. Nel connettore S3 si imposta come delimiter un carattere che nel file non compare — un asterisco — così l’ingestion non prova a spezzare le righe in colonne, e si attiva l’opzione per i file senza header. Il risultato è una landing table (nell’esempio, INITIAL) in cui tutto il contenuto sta in un’unica colonna, COLUMN_0.
Da lì il lavoro passa a SQL. Una view splitta COLUMN_0 sulla pipe generando colonne fino a COL52, con RECORD_NAME a identificare il segmento. Sui segmenti che contengono strutture annidate — l’esempio usa MSH e il suo campo MESSAGE_TYPE, con valori tipo ADT^01 — si applica lo stesso schema una seconda volta, splittando sul caret per ottenere main e sub message type. L’articolo riporta le varianti di sintassi per quattro destinazioni: element_at su Databricks, SPLIT con SAFE_OFFSET su BigQuery, get(SPLIT(…)) su Snowflake, SPLIT_PART su Redshift.
Il punto vero: late binding
La parte argomentativa è la contrapposizione tra early binding (l’ETL classico, che scarta i record non conformi già in fase di load) e late binding, dove il dato entra grezzo e viene interpretato dopo. Con HL7 la differenza è concreta: i segmenti non ancora modellati — PID, NK1, PV1 — restano comunque nella tabella INITIAL e possono essere estratti quando servono, e un file fuori standard non blocca il caricamento ma diventa un problema da investigare a valle.
Vale la pena ricordare che è contenuto vendor: la conclusione — usare i connettori file di Fivetran — è prevedibile, e la parte SQL non dipende dal tool. Resta anche un caveat implicito: una view piatta da 52 colonne è un punto di partenza, non un modello dati. L’autore rimanda a un capitolo successivo su come portare in produzione questo SQL con dbt.
In sintesi
- HL7 usa la pipe come field delimiter, non ha record delimiter e ammette record nested: servono due livelli di parsing.
- Il pattern proposto è ingestion grezza in una colonna unica e parsing via view SQL, con sintassi diversa su Snowflake, Databricks, BigQuery e Redshift.
- Il late binding evita che un file malformato blocchi il load, ma sposta il costo del modello dati a valle.
Hai qualcosa da aggiungere? Unisciti alla discussione.