Eksport do Apache Ossie
Apache Ossie (dawniej Open Semantic Interchange) to inkubowany projekt Apache definiujący przenośną specyfikację YAML/JSON do wymiany modeli semantycznych między narzędziami analitycznymi, AI i BI. Saiku dostarcza eksporter, który czyta dowolną schemę Mondrian i produkuje poprawny dokument Ossie — te same definicje miar i wymiarów stają się konsumowalne przez dbt, GoodData, Snowflake, Databricks, Salesforce i każde inne narzędzie z konwerterem Ossie.
Szybki start
Podaj schemę Mondrian XML na wejściu, otrzymaj YAML Ossie na wyjściu:
java -jar saiku-launcher/target/saiku-4.6.0.jar ossie-export \ --in saiku-home/data/Pharma.xml \ --out pharma.ossie.yamlLub użyj stdin/stdout do skryptowania:
cat schema.xml | saiku ossie-export > schema.ossie.yamlPolecenie wychodzi z niezerowym kodem, jeśli wejścia nie da się odczytać (exit 2) lub wyjścia nie da się zapisać (exit 3), z linią diagnostyczną na stderr. Udane przebiegi raportują, ile modeli semantycznych zapisano i (jeśli w ogóle) które kostki pominięto:
ossie-export: wrote 1 semantic model(s) to pharma.ossie.yamlCo mapuje się na co
Eksporter podąża za tą tabelą mapowania 1:1. Wszystko poza jawnie wylistowanymi wyjątkami ląduje w kolumnie docelowej dosłownie.
| Element Mondrian | Wyjście Ossie |
|---|---|
<Cube> | Jeden wpis semantic_model |
Faktowa <Table name="..." schema="..."/> kostki | Pierwszy dataset, source: "<schema>.<table>" |
<Dimension foreignKey="..."> z <Hierarchy><Table/> | Jeden dataset wymiarowy na hierarchię, plus jedna relationship z fact.foreignKey → dim.primaryKey |
<Level name="..." column="..."/> | Jedno field na wymiarze (lub fakcie, dla wymiarów zdegenerowanych), z expression.dialects[0]=ANSI_SQL:column |
<Level ... levelType="TimeYears"> (lub Quarters/Months/Days) | Pole zyskuje dimension.is_time: true |
<Measure name="..." column="..." aggregator="sum"/> | Jedna metric z oboma dialektami ANSI_SQL (SUM(fact.column)) oraz MDX ([Measures].[Name]) |
<Measure aggregator="distinct-count"> | ANSI_SQL: COUNT(DISTINCT fact.column) — plus count, min, max, avg wszystkie się tłumaczą |
<CalculatedMember><Formula>...</Formula></CalculatedMember> | Metryka z wyrażeniem tylko-MDX (brak niezawodnego tłumaczenia ANSI SQL dla formuł MDX) |
<Annotation name="saiku.semantic.description"> | ai_context.instructions elementu |
<Annotation name="saiku.semantic.synonyms"> | ai_context.synonyms[] elementu (podział CSV, przycięte) |
<Annotation name="saiku.semantic.pii">true | custom_extensions: [{vendor_name: SAIKU, data: '{"pii":true}'}] — boolean JSON, nie string |
<Annotation name="saiku.semantic.{cardinality,grain,aggregation_kind,required_filters}"> | To samo rozszerzenie dostawcy SAIKU, wartości serializowane jako stringi JSON |
Przykład — kostka Pharma
Wyciąg wejściowy z 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>Produkuje ten fragment 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]"Czego (jeszcze) nie obsługuje
Pierwsza wersja konwertera obsługuje klasyczny hybrydowy kształt Mondrian 3–4 używany przez Pharma, Bank i większość schem klientów. Nie obsługuje jeszcze:
- Kształtu opakowania Mondrian 4
<MeasureGroups>/<Dimensions>. FoodMart go używa. Kostki z tym kształtem są pomijane (raportowane na stderr) zamiast emitowane jako niepoprawne wobec schemy zaślepki. Praca kontynuacyjna śledzona na nadrzędnym epicu Ossie/SQL. - Kostek wirtualnych (
<VirtualCube>) — w tym naszego przykładu Warehouse-and-Sales. Pomijane jak powyżej. - Hierarchii parent-child. Emitowane jako płaskie poziomy; relacja hierarchiczna nie jest reprezentowalna w obecnym kształcie zorientowanym na zbiory danych w Ossie (grupa robocza hierarchii Ossie jest w toku — zobacz mapę drogową Ossie).
- Wymiarów współdzielonych konsumowanych przez
<DimensionUsage source=...>. Dziś działa tylko klasyczne osadzenie<Dimension>per-kostkę.
Gdy historia hierarchii w Ossie się ustabilizuje (cel: v0.3.0+), a konwerter MG Mondrian-4 Saiku wyląduje, ta tabela się skurczy.
Konsumowanie wyjścia
YAML Ossie jest sprawdzany walidacyjnie względem osi-schema.json z apache/ossie — każdy plik, który eksporter produkuje, przechodzi round-trip przez schemę z zerowymi znaleziskami (jest test jednostkowy, który to potwierdza przy każdym commicie). Konsumenci downstream:
- dbt — konwertery referencyjne Ossie zawierają moduł dbt.
- Snowflake, Salesforce, GoodData, Polaris, Databricks — ten sam katalog.
- Apache Superset i Metabase — brak jeszcze konwertera first-party w chwili pisania, ale praca nad SQL-over-Ossie na mapie drogowej Saiku (nadrzędny epic saiku#1387) sprawi, że samo Saiku będzie odpytywalne jako warstwa semantyczna przez SQL.
Powiązane
- Adnotacje semantyczne Saiku — klucze adnotacji, które eksporter czyta (mapujące się na
ai_context+custom_extensionsw Ossie). - Dobrze znane rozszerzenia Ossie — strona odbiorcza. Gdy twoja schema wyeksportuje się do YAML-a Ossie, dobrze znane
saiku.display/saiku.roles/saiku.piito sposób, w jaki autorujesz adnotacje bezpośrednio tam. - Struktura schemy — gdzie blok
<Annotations>żyje wewnątrz twojej schemy Mondrian. - Repozytorium apache/ossie — specyfikacja upstream, konwertery, mapa drogowa.