omni-to-databricks-metric-view

Par exploreomni · omni-agent-skills

Convertit un topic Omni Analytics en définition de Metric View Databricks dans Unity Catalog. Utilisez cette skill chaque fois que quelqu'un souhaite exporter des métriques Omni vers Databricks, créer une Metric View à partir d'un topic Omni, consolider des métriques BI dans Unity Catalog, ou faire le pont entre la couche sémantique d'Omni et les dashboards AI/BI ainsi que les espaces Genie de Databricks.

npx skills add https://github.com/exploreomni/omni-agent-skills --skill omni-to-databricks-metric-view

Omni → Vue métrique Databricks

Convertit un sujet Omni en vue métrique Databricks en explorant le modèle Omni via l'API, en traduisant ses définitions de champs au format YAML intégré des vues métriques Databricks, et en l'exécutant via la CLI Databricks.

Voir FIELD-MAPPING.md pour des exemples complets de traduction avant/après et YAML-REFERENCE.md pour la structure YAML complète, les tableaux de mapping des types d'agrégats et des formats.


Prérequis

# Vérifier que la CLI Omni est installée — sinon, demander à l'utilisateur de l'installer
# Voir : https://github.com/exploreomni/cli#readme
command -v omni >/dev/null || echo "ERROR: Omni CLI is not installed."
# Afficher les profils disponibles et sélectionner celui qui convient
omni config show
# S'il existe plusieurs profils, demander à l'utilisateur lequel utiliser, puis basculer :
omni config use <profile-name>
# CLI Databricks — vérifier qu'elle est installée et les profils
databricks --version
cat ~/.databrickscfg

Conseil : Utilisez -o json pour forcer une sortie structurée pour l'analyse programmatique, ou -o human pour des tableaux lisibles. La valeur par défaut est auto (human dans un TTY, JSON quand canalisé).

Flux de travail

Étape 1 — Recueillir les exigences

Demander à l'utilisateur :

  1. Quel sujet Omni souhaite-t-il convertir ? (p. ex., orders)
  2. Quelle est la destination du Catalog Unity ? (catalog.schema) (p. ex., main.sales)
  3. Quel est l'ID du SQL Warehouse Databricks ? (exécuter databricks sql warehouses list pour le trouver)
  4. S'agit-il d'une nouvelle vue métrique ou en existe-t-il déjà une à catalog.schema.[topic_name]_mv ?
  5. Quel profil CLI Databricks utiliser (optionnel — uniquement si l'utilisateur a plusieurs profils) ?

⚠️ ARRÊT — Confirmer toutes les réponses avant de continuer. La vue métrique sera nommée [topic_name]_mv par défaut.


Étape 2 — Explorer le modèle Omni

2a. Trouver l'ID du modèle

omni models list --modelkind SHARED

Identifier le modèle partagé et noter son id. Toujours préférer le modèle partagé aux modèles Schema ou Workbook.

2b. Récupérer le fichier sujet

omni models yaml-get <modelId> --filename <topic_name>.topic

Extraire du fichier sujet : base_view, joins, fields, always_filter, ai_context, sample_queries.

2c. Récupérer le fichier des relations

omni models yaml-get <modelId> --filename relationships

2d. Récupérer chaque fichier de vue référencé dans le sujet

Pour chaque vue dans base_view et joins :

omni models yaml-get <modelId> --filename <view_name>.view

Si une vue est préfixée par omni_dbt_, récupérer le fichier commençant par omni_dbt_. Ignorer toute vue sauvegardée par derived_table.sql — elle n'a pas de table physique.


Étape 3 — Identifier les tables et les jointures

Mapper les noms de vues aux références de table Databricks entièrement qualifiées (catalog.schema.table) :

Nom de vue Omni Table Databricks
ecomm__order_items catalog.ecomm.order_items
omni_dbt_ecomm__order_items catalog.ecomm.order_items (retirer omni_dbt_)

Le séparateur __ correspond au schéma (gauche) et à la table (droite). Confirmer le préfixe de catalogue avec l'utilisateur.

L'indentation joins définit la chaîne de jointure — une vue indentée sous une autre se joint à son parent :

joins:
  user_order_facts: {}          # ignorer — CTE dérivée
  ecomm__users: {}              # se joint à base_view
  ecomm__inventory_items:       # se joint à base_view
    ecomm__products:            # se joint à inventory_items

Trouver la dimension ayant primary_key: true dans chaque vue — la lister en premier parmi les dimensions de cette table.

ARRÊT — Confirmer la liste complète des tables et la hiérarchie de jointure avec l'utilisateur avant de continuer.


Étape 4 — Résoudre la liste des champs

Syntaxe Signification
(pas de paramètre fields) Inclure tous les champs de toutes les vues
all_views.* / view.* Inclure tous les champs de toutes les vues / de la vue nommée
tag:<value> Inclure tous les champs ayant ce tag
view.field Inclure ce champ spécifique
-view.field Exclure ce champ (gagne toujours sur les inclusions avec joker)

Traiter les inclusions en premier, puis appliquer les exclusions. Supprimer aussi tout champ ayant hidden: true sauf s'il est explicitement inclus par nom.


Étape 5 — Construire les définitions de jointure

Utilisant la hiérarchie de l'étape 3 et relationships.yaml, extraire les colonnes de jointure de on_sql et construire la clause on:. Utiliser le nom de la vue comme name de la jointure.

Schéma en étoile (niveau unique) :

joins:
  - name: ecomm__users
    source: catalog.ecomm.users
    'on': source.user_id = ecomm__users.id

Schéma en flocon de neige (multi-saut) :

joins:
  - name: ecomm__inventory_items
    source: catalog.ecomm.inventory_items
    'on': source.inventory_item_id = ecomm__inventory_items.id
    joins:
      - name: ecomm__products
        source: catalog.ecomm.products
        'on': ecomm__inventory_items.product_id = ecomm__products.id

⚠️ on est un mot réservé YAML 1.1 — toujours citer la clé en simple comme 'on':. Les colonnes des jointures imbriquées (2+ niveaux) ne peuvent pas être utilisées dans expr — les aplatir via une jointure directe dénormalisée à la place.


Étape 6 — Mapper les dimensions et les mesures

Pour chaque champ qui a survécu à l'étape 4, le traduire en utilisant les règles ci-dessous. Voir FIELD-MAPPING.md pour des exemples complets.

Référence rapide dimension :

Type de champ Omni Traduction Databricks
Chaîne/nombre standard expr: COLUMN
type: time (sans timeframes) Dimension timestamp simple
type: time + timeframes Une dimension DATE_TRUNC(...) par timeframe
groups: Expression CASE WHEN ... END
bin_boundaries: Expression CASE WHEN plage
duration: Expression DATEDIFF(unit, start, end)
type: yesno Dimension BOOLEAN (pas un filtre ; omettre data_type)

Référence rapide mesure :

Type de mesure Omni Traduction Databricks
aggregate_type: sum/avg/max/min SUM(col) / AVG(col) / etc.
aggregate_type: count COUNT(*)
aggregate_type: count_distinct COUNT(DISTINCT col)
Dérivée (référence d'autres mesures) MEASURE(measure_a) op MEASURE(measure_b) — définir les atomiques d'abord
filters: sur une mesure AGG(col) FILTER (WHERE condition)

Retirer les références Omni ${view.column} aux noms de colonnes nus (ou join_name.column pour les champs joints). Utiliser display_name pour le label Omni, comment pour description, et porter synonyms directement. Voir YAML-REFERENCE.md pour les tableaux de mapping des formats et des types d'agrégats.

Si le sujet a ai_context, le porter dans le comment au niveau supérieur de la vue métrique.

ARRÊT — Examiner toutes les dimensions, mesures et définitions de jointure avec l'utilisateur avant de générer la sortie finale.


Étape 7 — Vérifier l'existence d'une vue métrique

databricks api post /api/2.0/sql/statements \
  --json "{\"warehouse_id\": \"<WAREHOUSE_ID>\", \"statement\": \"SHOW VIEWS IN <catalog>.<schema> LIKE '%_mv'\", \"wait_timeout\": \"30s\", \"catalog\": \"<CATALOG>\", \"schema\": \"<SCHEMA>\"}"
  • Vue n'existe pas → utiliser CREATE OR REPLACE VIEW ... WITH METRICS
  • Vue existe déjà → utiliser ALTER VIEW ... AS $$ ... $$

Étape 8 — Générer et exécuter le SQL

Écrire le SQL dans un fichier temporaire :

-- CREATE (nouvelle vue)
CREATE OR REPLACE VIEW catalog.schema.orders_mv
WITH METRICS
LANGUAGE YAML
AS $$
version: 1.1
comment: "..."
source: catalog.ecomm.order_items

joins:
  - name: ecomm__users
    source: catalog.ecomm.users
    'on': source.user_id = ecomm__users.id

dimensions:
  - name: id
    expr: id
    display_name: "Order ID"

  - name: status
    expr: status
    display_name: "Order Status"

measures:
  - name: order_count
    expr: COUNT(*)
    display_name: "Order Count"

  - name: total_sale_price
    expr: SUM(sale_price)
    display_name: "Total Sale Price"
    format:
      type: currency
      currency_code: USD
$$
-- ALTER (vue existante)
ALTER VIEW catalog.schema.orders_mv AS $$
version: 1.1
...
$$

Exécuter via l'API SQL Statements (databricks sql execute n'existe pas dans CLI v0.295.0+) :

databricks api post /api/2.0/sql/statements \
  --json "{
    \"warehouse_id\": \"<WAREHOUSE_ID>\",
    \"statement\": $(cat /tmp/orders_mv.sql | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))'),
    \"wait_timeout\": \"50s\",
    \"catalog\": \"<CATALOG>\",
    \"schema\": \"<SCHEMA>\"
  }"

Vérifier la réponse pour "state": "SUCCEEDED". Si "state": "FAILED", lire status.error.message et voir la section Dépannage ci-dessous.

ARRÊT — Confirmer quel groupe ou quel utilisateur doit recevoir l'accès avant d'exécuter le GRANT. C'est un changement de permission visible par les autres.

Accorder l'accès :

databricks api post /api/2.0/sql/statements \
  --json "{\"warehouse_id\": \"<WAREHOUSE_ID>\", \"statement\": \"GRANT SELECT ON VIEW catalog.schema.orders_mv TO \`group_name\`\", \"wait_timeout\": \"30s\", \"catalog\": \"<CATALOG>\", \"schema\": \"<SCHEMA>\"}"

Dépannage

Quand l'API SQL Statements retourne "state": "FAILED", lire status.error.message :

Le message d'erreur contient Cause probable Correction
METRIC_VIEW_INVALID_VIEW_DEFINITION Champ ou valeur YAML invalide Vérifier le nom du champ par rapport aux clés valides (name, expr, display_name, comment, synonyms, format). Erreurs courantes : utiliser description au lieu de comment, decimal_places non supporté.
warehouse not running / RESOURCE_DOES_NOT_EXIST Warehouse arrêté ou ID incorrect Démarrer le warehouse dans l'interface Databricks ou vérifier l'ID avec databricks api get /api/2.0/sql/warehouses.
PERMISSION_DENIED Le profil CLI manque de privilèges Vérifier les permissions du profil sur le catalog/schéma avec databricks api get /api/2.0/unity-catalog/permissions/....
TABLE_OR_VIEW_NOT_FOUND Une table source ou de jointure n'existe pas dans Unity Catalog Vérifier chaque référence de table avec SHOW TABLES IN <catalog>.<schema>.
Erreur d'analyse on / clé inattendue on: non cité Toujours écrire 'on': (cité en simple) — c'est un mot réservé YAML 1.1.
Erreur de valeur wait_timeout Timeout hors limites wait_timeout doit être entre 5s et 50s.

Si le message d'erreur est tronqué, exécuter la même instruction avec "wait_timeout": "5s" pour obtenir la réponse d'erreur synchrone complète.


Règles critiques

  1. Nommage : Nommer la vue métrique [topic_name]_mv (snake_case, minuscules)
  2. CREATE vs ALTER : Vérifier l'existence en premier — CREATE OR REPLACE pour nouveau, ALTER VIEW pour existant
  3. Version : Toujours utiliser version: 1.1 (nécessite Databricks Runtime 17.2+)
  4. Ignorer les CTE dérivées : Les vues avec derived_table.sql n'ont pas de table physique — ignorer et avertir l'utilisateur
  5. Confirmer avant exécution : Montrer le SQL généré complet à l'utilisateur avant d'exécuter
  6. Champs booléens : Mapper type: yesno comme dimensions BOOLEAN — pas de filtres. data_type n'est pas un champ valide — l'omettre
  7. Mesures composées : Utiliser la syntaxe MEASURE() ; définir les mesures atomiques avant les composées
  8. Quoting YAML : on est un mot réservé YAML 1.1 — toujours écrire 'on': (cité en simple)
  9. Pas SELECT * : Tous les champs doivent être explicitement définis
  10. Colonnes MAP : Ignorer les jointures aux tables contenant des colonnes de type MAP — non supportées
  11. Références de jointures imbriquées : Seules les colonnes de jointure directe en étoile (1 niveau) peuvent être utilisées dans expr. Aplatir les jointures en flocon de neige via une jointure directe dénormalisée
  12. ID Warehouse requis : Toujours confirmer avant exécution — ne peut pas être déduit
  13. Les exclusions gagnent : -view.field remplace toujours n'importe quelle inclusion avec joker
  14. Les valeurs de type format sont minuscules : number, currency, date, date_time, percentage, byte
  15. Format de date requis : type: date et type: date_time nécessitent tous les deux date_format
  16. Format devise : Utiliser currency_code: USD pas iso_code: USD
  17. decimal_places non supporté : L'omettre entièrement — cause une erreur d'analyse
  18. Exécution CLI : Utiliser databricks api post /api/2.0/sql/statements ; wait_timeout doit être 5s50s
  19. Flag CLI Omni : Utiliser --filename (pas --file-name)
  20. Clé description de champ : Utiliser comment: pas description:description n'est pas un champ reconnu et cause une erreur d'analyse

Référence

Skills similaires