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 jsonpour forcer une sortie structurée pour l'analyse programmatique, ou-o humanpour des tableaux lisibles. La valeur par défaut estauto(human dans un TTY, JSON quand canalisé).
Flux de travail
Étape 1 — Recueillir les exigences
Demander à l'utilisateur :
- Quel sujet Omni souhaite-t-il convertir ? (p. ex.,
orders) - Quelle est la destination du Catalog Unity ? (
catalog.schema) (p. ex.,main.sales) - Quel est l'ID du SQL Warehouse Databricks ? (exécuter
databricks sql warehouses listpour le trouver) - S'agit-il d'une nouvelle vue métrique ou en existe-t-il déjà une à
catalog.schema.[topic_name]_mv? - 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]_mvpar 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 paromni_dbt_. Ignorer toute vue sauvegardée parderived_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
⚠️
onest 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 dansexpr— 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
- Nommage : Nommer la vue métrique
[topic_name]_mv(snake_case, minuscules) - CREATE vs ALTER : Vérifier l'existence en premier —
CREATE OR REPLACEpour nouveau,ALTER VIEWpour existant - Version : Toujours utiliser
version: 1.1(nécessite Databricks Runtime 17.2+) - Ignorer les CTE dérivées : Les vues avec
derived_table.sqln'ont pas de table physique — ignorer et avertir l'utilisateur - Confirmer avant exécution : Montrer le SQL généré complet à l'utilisateur avant d'exécuter
- Champs booléens : Mapper
type: yesnocomme dimensions BOOLEAN — pas de filtres.data_typen'est pas un champ valide — l'omettre - Mesures composées : Utiliser la syntaxe
MEASURE(); définir les mesures atomiques avant les composées - Quoting YAML :
onest un mot réservé YAML 1.1 — toujours écrire'on':(cité en simple) - Pas SELECT * : Tous les champs doivent être explicitement définis
- Colonnes MAP : Ignorer les jointures aux tables contenant des colonnes de type
MAP— non supportées - 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 - ID Warehouse requis : Toujours confirmer avant exécution — ne peut pas être déduit
- Les exclusions gagnent :
-view.fieldremplace toujours n'importe quelle inclusion avec joker - Les valeurs de type format sont minuscules :
number,currency,date,date_time,percentage,byte - Format de date requis :
type: dateettype: date_timenécessitent tous les deuxdate_format - Format devise : Utiliser
currency_code: USDpasiso_code: USD decimal_placesnon supporté : L'omettre entièrement — cause une erreur d'analyse- Exécution CLI : Utiliser
databricks api post /api/2.0/sql/statements;wait_timeoutdoit être5s–50s - Flag CLI Omni : Utiliser
--filename(pas--file-name) - Clé description de champ : Utiliser
comment:pasdescription:—descriptionn'est pas un champ reconnu et cause une erreur d'analyse