Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions converters/databricks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ Each row maps in both directions; the **Notes** flag where a behavior is specifi
| `dataset.fields[]` | `dimensions[]` | Export: fields flatten into one list and a joined column is qualified by its full join path (`customer.c_name`; `customer.region.r_name` when nested). |
| `field.expression.dialects[]` | `expr` | Export: prefer the `DATABRICKS` dialect, else `ANSI_SQL`. |
| `metrics[]` | `measures[]` | Export: fact columns are referenced bare (`SUM(amount)`). |
| `field.label` | `display_name` | |
| `field.label` | dimension `display_name` | A measure's `display_name` has no `label` on the Apache Ossie metric shape, so it rides in the stash instead (see the `custom_extensions` row). |
| `field` / `metric` `description` | `comment` | |
| `ai_context.synonyms` | `synonyms` | |
| `custom_extensions[DATABRICKS]` | `filter`, `window`, `format`, `rely`, `materialization` | Import stashes Metric View only features here; export restores them -- keeping `MV -> Apache Ossie -> MV` lossless. |
| `custom_extensions[DATABRICKS]` | `filter`, `window`, `format`, `rely`, `materialization`, measure `display_name` | Import stashes Metric View only features here; export restores them -- keeping `MV -> Apache Ossie -> MV` lossless. |

## Requirements

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
_MODEL_STASH_KEYS = ("filter", "parameters", "materialization")
_JOIN_STASH_KEYS = ("rely", "cardinality")
_COLUMN_STASH_KEYS = ("format", "window")
# A dimension's display_name maps to the field `label`, but a metric has no `label`, so a
# measure's display_name is stashed instead.
_MEASURE_STASH_KEYS = ("display_name",)


def _warn(scope, msg):
Expand Down Expand Up @@ -362,5 +365,6 @@ def _convert_measure(measure, fact_name):
metric["description"] = measure["comment"]
if measure.get("synonyms"):
metric["ai_context"] = {"synonyms": list(measure["synonyms"])}
write_stash(metric, {k: measure[k] for k in _COLUMN_STASH_KEYS if k in measure})
stash_keys = _COLUMN_STASH_KEYS + _MEASURE_STASH_KEYS
write_stash(metric, {k: measure[k] for k in stash_keys if k in measure})
return metric
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,8 @@ def _convert_metric(metric, fact, seen_names):
measure["format"] = stash["format"]
if "window" in stash:
measure["window"] = stash["window"]
if "display_name" in stash:
measure["display_name"] = stash["display_name"]
return measure


Expand Down
2 changes: 2 additions & 0 deletions converters/databricks/tests/_roundtrip_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ def build_metric_view(rnd):
m = {"name": names.next("c"), "expr": f"{rnd.pick(_AGGS)}({rnd.colname()})"}
if rnd.chance(0.4):
m["comment"] = rnd.text()
if rnd.chance(0.3):
m["display_name"] = rnd.text()
if rnd.chance(0.3):
m["synonyms"] = [rnd.text() for _ in range(rnd.count(1, 3))]
if rnd.chance(0.3):
Expand Down
18 changes: 18 additions & 0 deletions converters/databricks/tests/test_roundtrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,24 @@ def test_one_to_many_round_trips_mv_ossie_mv():
assert parse(mv_out) == parse(mv_in)


def test_measure_display_name_survives_round_trip_via_stash():
"""A measure's display_name survives MV -> Apache Ossie -> MV. A dimension's
display_name maps to the Apache Ossie field `label`, but the metric shape has no
`label`, so a measure's display_name rides in the DATABRICKS stash (like format/window)
and is restored on the way back (apache/ossie#326)."""
mv_in = (
"version: '1.1'\nsource: c.s.fact\n"
"dimensions:\n- {name: region, expr: region}\n"
"measures:\n- {name: total_revenue, expr: SUM(amount), display_name: Total Revenue}\n"
)
ossie = importer.convert_metric_view_to_ossie(mv_in)
# The only display_name in the input is on the measure; it must ride in the metric's
# stash, since there is no native Apache Ossie field for it.
assert "display_name" in ossie
mv_out = exporter.convert_ossie_to_metric_view(ossie)
assert parse(mv_out) == parse(mv_in)


# Property-based round-trip coverage. The Hypothesis driver lives in
# test_roundtrip_properties.py; these run the same generators/assertions under a plain
# seeded RNG so the property coverage also holds where Hypothesis is not installed.
Expand Down