Experimental, como vista_ejecutar_duckdb(). Traduce un ViewDefinition a una consulta SQL de
DuckDB que lee los recursos FHIR como JSON y
devuelve la tabla de la vista. Es el motor que usa
vista_ejecutar_duckdb(); esta función solo genera el texto, para
revisarlo o ejecutarlo en otra herramienta (por ejemplo la línea de
comandos de DuckDB).
Arguments
- vista
Un
ViewDefinitionen cualquier forma que aceptevista_leer().- desde
Origen de los recursos: rutas de archivos NDJSON (también comprimidos con gzip) o Parquet, o el nombre de una tabla o vista de DuckDB con una columna
json(un recurso FHIR por fila).
Details
El traductor cubre la estructura completa del ViewDefinition (select
anidados, column, forEach, forEachOrNull, repeat, unionAll,
where, constant y %rowIndex) y buena parte de FHIRPath:
navegación por campos (los elementos de elección como value o
effective buscan sus variantes valueQuantity, valueString...),
índices (name[0]), where(), select(), exists(), empty(),
all(), allTrue() y afines, count(), first(), last(), tail(),
skip(), take(), single(), distinct(), isDistinct(),
union()/|, combine(), intersect(), exclude(), subsetOf(),
supersetOf(), in, contains, not(), iif(), trace(), is,
as, ofType(), extension(url), getResourceKey(),
getReferenceKey(), funciones de texto (join(), startsWith(),
endsWith(), contains(), indexOf(), substring(), upper(),
lower(), trim(), length(), replace(), matches(),
replaceMatches(), split(), toChars()), conversiones (toString(),
toInteger(), toDecimal(), toBoolean() y sus convertsTo...()),
aritmética, abs(), ceiling(), floor(), round(), truncate(),
sqrt(), power() exacta, comparaciones de fechas y horas con su
precisión y lowBoundary()/highBoundary() de fechas y horas.
La traducción reproduce el resultado de fhirpath.js
(vista_ejecutar()). Si una expresión usa algo que no se puede traducir
con certeza, se produce un error de clase fhirviews_error_sql que
sugiere usar vista_ejecutar(); lo que solo se puede decidir con los
datos (por ejemplo, comparar una fecha sin hora con una fecha y hora, que
depende de la zona horaria del equipo, o textos con caracteres que DuckDB
y JavaScript pasan a mayúsculas de forma distinta) da un error al
ejecutar la consulta, nunca un resultado distinto.
Los elementos repeat se traducen hasta una profundidad fija (por
defecto 12 niveles; la opción fhirviews.sql_profundidad la cambia); si
los datos tienen más niveles, la consulta produce un error en lugar de
omitir filas.
Los tipos de las columnas salen del type de cada columna, del tipo
de la expresión o, si no, del modelo FHIR R4. Las columnas cuyo tipo no
se puede deducir quedan como JSON; vista_ejecutar_duckdb() las
convierte después según los valores.
See also
vista_ejecutar_duckdb() para ejecutarla.
Examples
vista <- vista_crear("Patient", c(sexo = "gender",
apellido = "name.first().family"))
vista_sql(vista, "pacientes.ndjson")
#> SELECT f."id" AS "id", f."sexo" AS "sexo", f."apellido" AS "apellido"
#> FROM (
#> SELECT unnest([{'id': json_extract_string(r, '$.id'), 'sexo': json_extract_string(list_extract(list_transform([flatten(list_transform([json_extract(r, '$."gender"')], lambda z1: CASE WHEN z1 IS NULL OR CAST(z1 AS VARCHAR) = 'null' THEN []::JSON[] WHEN starts_with(CAST(z1 AS VARCHAR), '[') THEN list_filter(CAST(z1 AS JSON[]), lambda z2: z2 IS NOT NULL AND CAST(z2 AS VARCHAR) <> 'null') ELSE [z1] END))], lambda z3: CASE WHEN len(z3) > 1 THEN error('La columna sexo devolvió varios valores para una fila; usa collection: true o first()') ELSE z3[1] END), 1), '$'), 'apellido': json_extract_string(list_extract(list_transform([flatten(list_transform([json_extract(list_extract(flatten(list_transform([json_extract(r, '$."name"')], lambda z4: CASE WHEN z4 IS NULL OR CAST(z4 AS VARCHAR) = 'null' THEN []::JSON[] WHEN starts_with(CAST(z4 AS VARCHAR), '[') THEN list_filter(CAST(z4 AS JSON[]), lambda z5: z5 IS NOT NULL AND CAST(z5 AS VARCHAR) <> 'null') ELSE [z4] END)), 1), '$."family"')], lambda z6: CASE WHEN z6 IS NULL OR CAST(z6 AS VARCHAR) = 'null' THEN []::JSON[] WHEN starts_with(CAST(z6 AS VARCHAR), '[') THEN list_filter(CAST(z6 AS JSON[]), lambda z7: z7 IS NOT NULL AND CAST(z7 AS VARCHAR) <> 'null') ELSE [z6] END))], lambda z8: CASE WHEN len(z8) > 1 THEN error('La columna apellido devolvió varios valores para una fila; usa collection: true o first()') ELSE z8[1] END), 1), '$')}]) AS f
#> FROM (SELECT json AS r FROM read_json_objects(['pacientes.ndjson'], format = 'newline_delimited'))
#> WHERE json_extract_string(r, '$.resourceType') = 'Patient'
#> )
