Los recursos FHIR están optimizados para la interoperabilidad, mientras que las plataformas de analítica como Databricks funcionan mejor con tablas. Los equipos de analítica sanitaria se topan constantemente con esa brecha: necesitan datos FHIR dentro de Databricks para informes, investigación, aprendizaje automático y analítica de salud poblacional, pero los datos llegan como JSON anidado en lugar de filas.
Desde Aidbox 2605, puede cerrar esa brecha directamente: exporte ViewDefinitions de SQL on FHIR directamente a tablas Delta administradas por Databricks Unity Catalog. Este artículo muestra cómo construir ese pipeline usando:
$viewdefinition-exportpara instantáneas y recargas históricasAidboxTopicDestinationpara entrega continua con exportación inicial automática
¿Por qué Databricks para la analítica FHIR?
FHIR es un buen formato para intercambiar datos sanitarios, pero no es una forma conveniente para la analítica. Los equipos de analítica quieren consultar cohortes, construir paneles de control, unir datos clínicos con datos operativos y preparar conjuntos de datos para investigación o aprendizaje automático — y Databricks les ofrece una plataforma lakehouse diseñada exactamente para eso:
- Tablas Delta Lake para almacenamiento analítico
- Unity Catalog para gobernanza
- Databricks SQL para consultas
- Notebooks y Jobs para el procesamiento de datos
- Flujos de trabajo de ML e IA sobre las mismas tablas
La pieza que faltaba es la transformación de FHIR a tabla, y eso es precisamente lo que proporcionan las ViewDefinitions de SQL on FHIR: definen cómo los recursos FHIR se convierten en filas analíticas antes de que esas filas lleguen a Databricks.
Convierta recursos FHIR en tablas analíticas
Los recursos FHIR son JSON anidado, pero la mayoría de las cargas de trabajo analíticas necesitan tablas relacionales. Ese desajuste es habitualmente donde comienza el problema: alguien construye un pipeline ETL, otra persona lo mantiene, y seis meses después el pipeline se ha convertido en un producto propio.
Aidbox resuelve esto con SQL on FHIR: defina una ViewDefinition y los recursos FHIR se convierten en filas.
{
"resourceType": "ViewDefinition",
"id": "patient_flat",
"resource": "Patient",
"select": [
{
"column": [
{ "name": "id", "path": "id" },
{ "name": "ts", "path": "getAidboxTs()" },
{ "name": "gender", "path": "gender" },
{ "name": "birth_date", "path": "birthDate" },
{ "name": "family_name", "path": "name.where(use = 'official').family.first()" },
{ "name": "given_name", "path": "name.where(use = 'official').given.first()" }
]
}
]
}
Qué hace esto
Esta ViewDefinition toma recursos Patient y los convierte en filas analíticas aplanadas.
resource: Patientselecciona el tipo de recurso FHIR de origen.id,gender,birth_date,family_nameygiven_namese convierten en columnas de la tabla.getAidboxTs()añade una columna de marca de tiempo utilizada para exportaciones incrementales.- Tras la materialización, Aidbox expone el resultado como
sof.patient_flat.
Materialice la vista:
POST /fhir/ViewDefinition/patient_flat/$materialize
Un recurso Patient:
{
"resourceType": "Patient",
"id": "patient-1",
"gender": "male",
"birthDate": "1990-01-15",
"name": [
{
"use": "official",
"family": "Smith",
"given": ["John"]
}
]
}
se convierte en una fila que puede consultar:
SELECT id, ts, gender, birth_date, family_name, given_name
FROM sof.patient_flat;
| id | ts | gender | birth_date | family_name | given_name |
|---|---|---|---|---|---|
| patient-1 | 2026-06-09T10:15:00Z | male | 1990-01-15 | Smith | John |
Aidbox expone el resultado como la vista PostgreSQL sof.patient_flat, que se convierte en el origen tanto para exportaciones por lotes como para la entrega continua.
¿No está familiarizado con SQL on FHIR?
Lea nuestros artículos:
Entrega continua de FHIR a Databricks
Las suscripciones basadas en tópicos de Aidbox son la capa de eventos detrás de la entrega continua — semántica de al menos una vez, destino de solo adición. Usted define un AidboxSubscriptionTopic para los cambios de recursos que le interesan y luego adjunta un AidboxTopicDestination que decide adónde deben ir esos eventos. En este caso, el destino no es un webhook ni una cola — es un escritor de Data Lakehouse que toma filas de la ViewDefinition de SQL on FHIR y las entrega a Databricks.
Cree un tópico que escuche los cambios en Patient:
POST /fhir/AidboxSubscriptionTopic
{
"resourceType": "AidboxSubscriptionTopic",
"url": "http://example.org/subscriptions/patient-updates",
"status": "active",
"trigger": [
{
"resource": "Patient",
"supportedInteraction": ["create", "update", "delete"]
}
]
}
Cree un destino Data Lakehouse:
{
"resourceType": "AidboxTopicDestination",
"id": "patient-databricks",
"topic": "http://example.org/subscriptions/patient-updates",
"kind": "data-lakehouse-at-least-once",
"parameter": [
// ... databricks params ...
{ "name": "viewDefinition",
"valueString": "patient_flat"
},
{ "name": "batchSize",
"valueUnsignedInt": 50
},
{ "name": "sendIntervalMs",
"valueUnsignedInt": 5000
}
]
}
Qué hace esto
Este destino envía filas de SQL on FHIR a Databricks cada vez que cambia un recurso FHIR que coincide con el tópico.
topic— el tópico de suscripción al que escuchar.viewDefinition— la forma de tabla aplanada a enviar.batchSize— cuántas filas van en un lote de entrega.sendIntervalMs— con qué frecuencia se vacían las filas pendientes.// ... databricks params ...— campos de conexión específicos de Databricks, omitidos por claridad. Consulte Data Lakehouse AidboxTopicDestination.
Cree un Patient:
POST /fhir/Patient
{
"name": [
{
"use": "official",
"family": "Smith",
"given": ["John"]
}
],
"gender": "male",
"birthDate": "1990-01-15"
}
Compruebe Databricks:
SELECT id, ts, gender, birth_date, family_name, given_name, is_deleted
FROM aidbox_export.fhir.patients;
| id | ts | gender | birth_date | family_name | given_name | is_deleted |
|---|---|---|---|---|---|---|
| patient-1 | 2026-06-09T10:15:00Z | male | 1990-01-15 | Smith | John | 0 |
El motor de exportación añade una columna is_deleted a la tabla de destino para que las consultas posteriores puedan filtrar los recursos eliminados sin perder su historial.
La exportación inicial de FHIR viene incluida
La mayoría de los sistemas ya contienen datos antes de que comience el primer flujo. Cuando AidboxTopicDestination se inicia, exporta automáticamente el estado actual de cada fila de la ViewDefinition antes de cambiar a la entrega en directo — sin trabajo de arranque separado, sin script de migración personalizado, sin pipeline dual. Las filas históricas se convierten en el punto de partida, y las nuevas actualizaciones continúan a través del flujo en directo.
Este es el comportamiento predeterminado. Si solo desea los datos nuevos desde el momento en que se crea el destino, añada skipInitialExport: true al array parameter del destino:
{ "name": "skipInitialExport", "valueBoolean": true }
Más información en la documentación de Aidbox:
👉 Exportación inicial para Data Lakehouse AidboxTopicDestination
Exportación por lotes de FHIR a Delta Lake
¿Necesita una instantánea puntual en lugar de un flujo continuo? Use $viewdefinition-export.
POST /fhir/ViewDefinition/$viewdefinition-export
Prefer: respond-async
{
"resourceType": "Parameters",
"parameter": [
{
"name": "view",
"part": [
{
"name": "name",
"valueString": "patient_flat"
},
{
"name": "viewReference",
"valueReference": {
"reference": "ViewDefinition/patient_flat"
}
}
]
},
{
"name": "kind",
"valueString": "data-lakehouse"
}
// ... databricks parameters ...
]
}
Exportación puntual
Use $viewdefinition-export cuando necesite un trabajo por lotes controlado en lugar de entrega continua.
Casos típicos:
- instantáneas puntuales
- recargas históricas
- exportaciones programadas
- trabajos de recuperación
- bucles de exportación incremental con
_since
La operación se ejecuta de forma asíncrona y devuelve una URL de estado en la cabecera Content-Location.
Respuesta:
202 Accepted
Content-Location: /fhir/ViewDefinition/$viewdefinition-export/status/<export-id>
Compruebe el estado:
GET /fhir/ViewDefinition/$viewdefinition-export/status/<export-id>
Cuando la exportación finaliza:
{
"resourceType": "Parameters",
"parameter": [
{
"name": "status",
"valueCode": "completed"
},
{
"name": "output",
"part": [
{
"name": "location",
"valueUri": "databricks-uc:aidbox_export.fhir.patients"
}
]
}
]
}
Consulte la tabla resultante desde Databricks SQL:
SELECT id, ts, gender, birth_date, family_name, given_name, is_deleted
FROM aidbox_export.fhir.patients;
| id | ts | gender | birth_date | family_name | given_name | is_deleted |
|---|---|---|---|---|---|---|
| patient-1 | 2026-06-09T10:15:00Z | male | 1990-01-15 | Smith | John | 0 |
| patient-2 | 2026-06-09T10:18:00Z | female | 1984-07-22 | Garcia | Maria | 0 |
| patient-3 | 2026-06-09T10:24:00Z | other | 2001-03-08 | Chen | Alex | 0 |
| patient-4 | 2026-06-09T10:31:00Z | female | 1976-11-30 | Okafor | Amara | 0 |
Exportaciones incrementales de FHIR
¿Necesita una exportación incremental nocturna en lugar de un flujo continuo? Use _since. Aidbox filtra las filas por la columna de marca de tiempo de la ViewDefinition generada a partir de getAidboxTs(), de modo que la exportación solo contiene las filas modificadas después de la marca de agua que usted indica. Reutilice la misma solicitud $viewdefinition-export mostrada anteriormente y añada un parámetro más:
{
"name": "_since",
"valueInstant": "2026-01-01T00:00:00Z"
}
Para ejecutar exportaciones incrementales de forma programada, avance _since después de cada ejecución:
- Ejecute
$viewdefinition-exportcon_since. - Espere hasta que el estado de la exportación sea
completed. - Lea
exportEndTimede la respuesta completada y guárdelo. - Use ese valor como
_sinceen la siguiente ejecución.
Esto le proporciona exportaciones incrementales programadas sin necesidad de construir un pipeline de seguimiento de cambios separado.
AidboxTopicDestination frente a $viewdefinition-export
AidboxTopicDestination | $viewdefinition-export | |
|---|---|---|
| Entrega | Continua, dirigida por eventos | Puntual, ejecutada bajo demanda |
| Exportación inicial | Automática | Manual |
| Actualizaciones | Casi en tiempo real, por cambio de recurso | Por lotes, por solicitud |
| Incremental | Integrada mediante tópicos de suscripción | Manual mediante _since |
| Mejor opción para | Pipelines de producción que mantienen las tablas de Databricks actualizadas continuamente | Instantáneas, recargas históricas, trabajos programados, recuperación y repetición |
Cómo funciona la exportación de FHIR a Delta Lake
Tanto la exportación inicial de AidboxTopicDestination como $viewdefinition-export utilizan el mismo motor de exportación, que:
- Lee filas de la vista PostgreSQL materializada
sof.<view>. - Divide la exportación en múltiples fragmentos.
- Escribe tablas Delta de staging en S3.
- Ejecuta una operación
MERGE INTOfinal contra la tabla administrada por Unity Catalog.
El resultado es una tabla Databricks Delta Lake que puede consultar desde Databricks SQL, notebooks, paneles de control o herramientas de analítica posteriores.
Para exportaciones grandes, los fragmentos pueden procesarse en paralelo en múltiples pods de Aidbox.
Otros destinos de analítica FHIR
Databricks no es el único destino de analítica compatible. Si utiliza ClickHouse, consulte ClickHouse AidboxTopicDestination; para BigQuery, consulte BigQuery AidboxTopicDestination. Ambos destinos utilizan el mismo enfoque de ViewDefinition de SQL on FHIR y el mismo modelo de entrega continua.
Más allá de las exportaciones
Para una integración más estrecha, Aidbox puede ejecutarse de forma nativa en Databricks Lakebase — consulte Building a FHIR-native health data platform on Databricks Lakebase para conocer la arquitectura, o Health Samurai + Databricks para los detalles de la colaboración.
Conclusión
Los recursos FHIR están optimizados para la interoperabilidad y Databricks está optimizado para la analítica. Las ViewDefinitions de SQL on FHIR salvan esa brecha transformando los recursos FHIR en tablas analíticas. Use $viewdefinition-export cuando necesite instantáneas, recargas históricas o exportaciones incrementales, y AidboxTopicDestination cuando necesite entrega continua y una carga inicial automática. En cualquier caso, Databricks Delta Lake recibe filas analíticas aplanadas en lugar de JSON FHIR anidado.
Lecturas adicionales:
🤔 ¿Tiene alguna pregunta?
Pregúntenos en el chat de Zulip: https://connect.health-samurai.io/



