Exportando para Apache Ossie
Apache Ossie (antigo Open Semantic Interchange) é um projeto Apache em incubação que define uma especificação YAML/JSON portável para troca de modelos semânticos entre ferramentas de analytics, AI e BI. O Saiku distribui um exportador que lê qualquer schema Mondrian e produz um documento Ossie válido — as mesmas definições de measure e dimension tornam-se consumíveis por dbt, GoodData, Snowflake, Databricks, Salesforce e toda outra ferramenta com um conversor Ossie.
Início rápido
Passe um schema XML Mondrian, obtenha YAML Ossie de saída:
java -jar saiku-launcher/target/saiku-4.6.0.jar ossie-export \ --in saiku-home/data/Pharma.xml \ --out pharma.ossie.yamlOu use stdin/stdout para scripting:
cat schema.xml | saiku ossie-export > schema.ossie.yamlO comando sai com código não-zero se o input não pode ser lido (exit 2) ou o output não pode ser escrito (exit 3), com uma linha de diagnóstico em stderr. Runs bem-sucedidos reportam quantos modelos semânticos foram escritos e (se algum) quais cubos foram pulados:
ossie-export: wrote 1 semantic model(s) to pharma.ossie.yamlO que mapeia para o quê
O exportador segue esta tabela de mapeamento 1:1. Tudo exceto exceções explicitamente listadas cai na coluna alvo verbatim.
| Elemento Mondrian | Saída Ossie |
|---|---|
<Cube> | Uma entrada semantic_model |
Fact <Table name="..." schema="..."/> do cubo | Primeiro dataset, source: "<schema>.<table>" |
<Dimension foreignKey="..."> com <Hierarchy><Table/> | Um dataset de dim por hierarquia, mais um relationship de fact.foreignKey → dim.primaryKey |
<Level name="..." column="..."/> | Um field na dim (ou fact, para dims degeneradas), com expression.dialects[0]=ANSI_SQL:column |
<Level ... levelType="TimeYears"> (ou Quarters/Months/Days) | Field ganha dimension.is_time: true |
<Measure name="..." column="..." aggregator="sum"/> | Uma metric com ambos os dialetos ANSI_SQL (SUM(fact.column)) e MDX ([Measures].[Name]) |
<Measure aggregator="distinct-count"> | ANSI_SQL: COUNT(DISTINCT fact.column) — mais count, min, max, avg todos traduzem |
<CalculatedMember><Formula>...</Formula></CalculatedMember> | Metric com expressão só-MDX (sem tradução ANSI SQL confiável para fórmulas MDX) |
<Annotation name="saiku.semantic.description"> | ai_context.instructions do elemento |
<Annotation name="saiku.semantic.synonyms"> | ai_context.synonyms[] do elemento (split por CSV, aparado) |
<Annotation name="saiku.semantic.pii">true | custom_extensions: [{vendor_name: SAIKU, data: '{"pii":true}'}] — booleano JSON, não string |
<Annotation name="saiku.semantic.{cardinality,grain,aggregation_kind,required_filters}"> | Mesma extensão de fornecedor SAIKU, valores serializados como strings JSON |
Exemplo trabalhado — cubo Pharma
Trecho de input 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>Produz este fragmento Ossie:
version: 0.2.0.dev0semantic_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]"O que (ainda) não é suportado
O conversor de primeira geração trata o formato híbrido clássico Mondrian 3–4 usado por Pharma, Bank e a maioria dos schemas de clientes. Ele ainda não trata:
- Formato wrapper
<MeasureGroups>/<Dimensions>do Mondrian 4. FoodMart usa isso. Cubos com este formato são pulados (reportado em stderr) em vez de emitidos como stubs schema-inválidos. Trabalho de follow-up rastreado no épico pai Ossie/SQL. - Cubos virtuais (
<VirtualCube>) — incluindo nosso exemplo Warehouse-and-Sales. Pulados como acima. - Hierarquias parent-child. Emitidas como levels planos; a relação hierárquica não é representável no formato atual orientado a dataset do Ossie (o grupo de trabalho de hierarquia do Ossie está em andamento — veja o roadmap do Ossie).
- Shared dimensions consumidas via
<DimensionUsage source=...>. Só o embedding clássico por-cubo<Dimension>funciona hoje.
Quando a história de hierarquia do Ossie estabilizar (alvo: v0.3.0+) e o conversor de MG Mondrian-4 do Saiku chegar, esta tabela vai encolher.
Consumindo a saída
O YAML Ossie é verificado por validação contra o osi-schema.json do apache/ossie — todo arquivo que o exportador produz faz round-trip pelo schema com zero achados (há um teste de unidade que assevera isso em cada commit). Consumidores downstream:
- dbt — os conversores de referência do Ossie incluem um módulo dbt.
- Snowflake, Salesforce, GoodData, Polaris, Databricks — mesmo diretório.
- Apache Superset e Metabase — sem conversor de primeira parte ainda no momento da escrita, mas o trabalho de SQL-sobre-Ossie no roadmap do Saiku (épico pai saiku#1387) fará o próprio Saiku consultável como uma camada semântica via SQL.
Relacionado
- Anotações semânticas do Saiku — as chaves de anotação que o exportador lê (que mapeiam no
ai_context+custom_extensionsdo Ossie). - Extensões well-known do Ossie — a ponta receptora. Uma vez que seu schema exporta para YAML Ossie, os well-knowns
saiku.display/saiku.roles/saiku.piisão como você autora anotações diretamente lá. - Estrutura do schema — onde o bloco
<Annotations>vive dentro do seu schema Mondrian. - Repositório apache/ossie — spec upstream, conversores, roadmap.