Saltearse al contenido

Exportar a Apache Ossie

Apache Ossie (antes Open Semantic Interchange) es un proyecto Apache en incubación que define una especificación portable YAML/JSON para el intercambio de modelos semánticos entre herramientas de analítica, IA y BI. Saiku entrega un exportador que lee cualquier schema Mondrian y produce un documento Ossie válido — las mismas definiciones de medida y dimensión se vuelven consumibles por dbt, GoodData, Snowflake, Databricks, Salesforce, y cualquier otra herramienta con un conversor de Ossie.

Inicio rápido

Pase un schema XML Mondrian, obtenga YAML Ossie:

Ventana de terminal
java -jar saiku-launcher/target/saiku-4.6.0.jar ossie-export \
--in saiku-home/data/Pharma.xml \
--out pharma.ossie.yaml

O use stdin/stdout para scripting:

Ventana de terminal
cat schema.xml | saiku ossie-export > schema.ossie.yaml

El comando sale con código distinto de cero si la entrada no se puede leer (exit 2) o la salida no se puede escribir (exit 3), con una línea de diagnóstico en stderr. Las ejecuciones exitosas reportan cuántos modelos semánticos se escribieron y (si los hay) qué cubos se saltaron:

ossie-export: wrote 1 semantic model(s) to pharma.ossie.yaml

Qué mapea a qué

El exportador sigue esta tabla de mapeo 1:1. Todo excepto las excepciones listadas explícitamente aterriza en la columna destino literalmente.

Elemento MondrianSalida Ossie
<Cube>Una entrada semantic_model
<Table name="..." schema="..."/> de hechos del cuboPrimer dataset, source: "<schema>.<table>"
<Dimension foreignKey="..."> con <Hierarchy><Table/>Un dataset de dim por jerarquía, más una relationship de fact.foreignKey → dim.primaryKey
<Level name="..." column="..."/>Un field en la dim (o hechos, para dims degeneradas), con expression.dialects[0]=ANSI_SQL:column
<Level ... levelType="TimeYears"> (o Quarters/Months/Days)El field gana dimension.is_time: true
<Measure name="..." column="..." aggregator="sum"/>Una metric con ambos dialectos ANSI_SQL (SUM(fact.column)) y MDX ([Measures].[Name])
<Measure aggregator="distinct-count">ANSI_SQL: COUNT(DISTINCT fact.column) — más count, min, max, avg todos se traducen
<CalculatedMember><Formula>...</Formula></CalculatedMember>Métrica con expresión MDX-only (sin traducción ANSI SQL fiable para fórmulas MDX)
<Annotation name="saiku.semantic.description">ai_context.instructions del elemento
<Annotation name="saiku.semantic.synonyms">ai_context.synonyms[] del elemento (CSV dividido, recortado)
<Annotation name="saiku.semantic.pii">truecustom_extensions: [{vendor_name: SAIKU, data: '{"pii":true}'}] — booleano JSON, no cadena
<Annotation name="saiku.semantic.{cardinality,grain,aggregation_kind,required_filters}">La misma extensión de proveedor SAIKU, valores serializados como cadenas JSON

Ejemplo trabajado — cubo Pharma

Extracto de entrada de saiku-home/data/Pharma.xml:

<Cube name="Pharma Rx">
<Table name="fact_pharma" schema="public"/>
<Dimension name="Prescriber" foreignKey="prescriberkey">
<Hierarchy hasAll="true" primaryKey="prescriberkey">
<Table name="dim_prescriber" schema="public"/>
<Level name="Prescriber" column="prescriberkey" nameColumn="prescribername"
type="Numeric" uniqueMembers="true">
<Annotations>
<Annotation name="saiku.semantic.pii">true</Annotation>
</Annotations>
</Level>
</Hierarchy>
</Dimension>
<Measure name="Quantity" column="quantity_units" aggregator="sum" formatString="#,##0"/>
</Cube>

Produce este fragmento Ossie:

version: 0.2.0.dev0
semantic_model:
- name: Pharma Rx
datasets:
- name: fact_pharma
source: public.fact_pharma
description: Fact table for cube 'Pharma Rx'.
- name: Prescriber
source: public.dim_prescriber
primary_key:
- prescriberkey
fields:
- name: Prescriber
expression:
dialects:
- dialect: ANSI_SQL
expression: prescriberkey
custom_extensions:
- vendor_name: SAIKU
data: "{\"pii\":true}"
relationships:
- name: fact_pharma_to_Prescriber
from: fact_pharma
to: Prescriber
from_columns:
- prescriberkey
to_columns:
- prescriberkey
metrics:
- name: Quantity
expression:
dialects:
- dialect: ANSI_SQL
expression: SUM(fact_pharma.quantity_units)
- dialect: MDX
expression: "[Measures].[Quantity]"

Qué (todavía) no está soportado

El conversor de primer corte maneja la forma híbrida clásica de Mondrian 3–4 usada por Pharma, Bank, y la mayoría de los schemas de clientes. No maneja aún:

  • La forma envoltorio de Mondrian 4 <MeasureGroups> / <Dimensions>. FoodMart usa esto. Los cubos con esta forma se saltan (reportado a stderr) en lugar de emitirse como stubs inválidos para el schema. El trabajo de seguimiento se rastrea en el epic padre de Ossie/SQL.
  • Cubos virtuales (<VirtualCube>) — incluyendo nuestro ejemplo Warehouse-and-Sales. Se saltan como arriba.
  • Jerarquías padre-hijo. Se emiten como niveles planos; la relación jerárquica no es representable en la forma orientada a datasets actual de Ossie (el grupo de trabajo de jerarquías de Ossie está en marcha — vea el roadmap de Ossie).
  • Dimensiones compartidas consumidas mediante <DimensionUsage source=...>. Solo funciona hoy la incrustación clásica de <Dimension> por cubo.

Cuando la historia de jerarquías de Ossie se estabilice (objetivo: v0.3.0+) y aterrice el conversor de MG de Mondrian 4 de Saiku, esta tabla encogerá.

Consumir la salida

El YAML Ossie se valida contra el osi-schema.json de apache/ossie — cada archivo que el exportador produce hace round-trip a través del schema con cero hallazgos (hay un test unitario que lo afirma en cada commit). Consumidores aguas abajo:

  • dbt — los conversores de referencia de Ossie incluyen un módulo dbt.
  • Snowflake, Salesforce, GoodData, Polaris, Databricks — mismo directorio.
  • Apache Superset y Metabase — aún sin conversor de primera parte al momento de escribir, pero el trabajo de SQL-sobre-Ossie en el roadmap de Saiku (epic padre saiku#1387) hará al propio Saiku consultable como capa semántica vía SQL.

Relacionado