Summary
When importing a Fabric / Power BI TMDL model, the Microsoft converter does not treat a common “blank” or measure-only table as a valid host for measures. TMDL allows tables that exist primarily to hold measures (often with no real business columns, or only a dummy calculated column/partition). Today those tables are classified as calculated tables, excluded from the Ossie model, and their measures are preserved only inside the Power BI custom_extensions stash—rather than being mapped to first-class Ossie metrics.
Background
In TMDL / tabular models it is valid and common to define a table whose purpose is organizational: hold measures in one place (for example a *_Measures table), without modeling it as a real dataset end users query for columns.
A typical shape is:
- a table with little or no meaningful source data
- optionally a dummy calculated partition such as a single blank row
- optionally a hidden dummy calculated column
- one or more measures with normal DAX expressions
TMDL allows this. Measure evaluation does not require the host table to be a normal imported fact/dimension table.
Current behavior
On TMDL → Ossie import (convert_semantic_model_to_ossie):
- Tables are filtered before measure conversion. A table is excluded when it is treated as a calculated table (partition
source.type == "calculated"), among other exclusion rules (private tables, calculation groups, auto date tables).
- Excluded tables are omitted from
semantic_model.datasets.
- The full TMSL/TMDL table object—including its
measures—is written into the model-level POWER_BI custom_extensions payload under excludedTables.
- Measure → metric conversion only walks non-excluded tables. Measures that live only on an excluded blank/measure-only table therefore never become Ossie
metrics[].
Observed warning pattern:
[table '<MeasureTable>'] calculated tables are not converted to Apache Ossie; excluded from the Apache Ossie model and preserved in custom_extensions
Illustrative TMDL (generic)
table MeasureTable
lineageTag: ...
measure 'Total Amount' =
SUM(FactTable[Amount])
formatString: #,0.00
displayFolder: Finance\Amounts
lineageTag: ...
/// often present on measure-only tables
partition MeasureTable = calculated
mode: import
source =
Row("Column", BLANK())
column _
type: calculatedTableColumn
isHidden
...
Illustrative Ossie outcome (generic)
Instead of:
semantic_model:
- name: ...
datasets:
- name: FactTable
...
metrics:
- name: Total Amount
expression:
dialect: DAX
expression: SUM(FactTable[Amount])
custom_extensions:
- vendor_name: POWER_BI
data: '{"table":"MeasureTable", ...}'
the measure information is effectively only recoverable from the model stash, conceptually:
semantic_model:
- name: ...
datasets:
- name: FactTable
...
# no metric for Total Amount
custom_extensions:
- vendor_name: POWER_BI
data: |
{
"excludedTables": [
{
"name": "MeasureTable",
"partitions": [
{
"source": {
"type": "calculated",
"expression": "Row(\"Column\", BLANK())"
}
}
],
"measures": [
{
"name": "Total Amount",
"expression": "SUM(FactTable[Amount])",
"formatString": "#,0.00",
"displayFolder": "Finance\\Amounts"
}
]
}
]
}
Round-trip may still preserve the Power BI objects via the stash, but the portable Ossie document does not surface those measures as metrics.
Why this is a problem
- Loss of portable semantics: DAX measures are core semantic content. Putting them only in vendor stash means non-Power-BI consumers of the Ossie document never see them.
- Mismatch with TMDL validity: A blank/measure-only table is a legitimate TMDL construct. Excluding it as if it were only an engine implementation detail over-fits the “calculated table ≠ dataset” rule.
- Conflates two concerns:
- “Do not expose this table as an Ossie dataset/source” (reasonable for dummy calculated hosts)
- “Do not import measures defined on this table as Ossie metrics” (much less reasonable)
- Surprising empty metrics list: A model can import with many tables and zero metrics solely because all measures lived on one excluded host table.
Expected behavior
More ideal import behavior would separate table exclusion from measure import:
- Continue omitting true non-dataset tables from
datasets when appropriate (dummy calculated hosts, private tables, etc.), or represent measure-only hosts in a clearly documented way if Ossie gains a better home for them.
- Still convert measures on those tables into Ossie
metrics with dialect: DAX, preserving description/format metadata via metric-level custom_extensions as already done for measures on normal tables.
- Keep enough stash metadata to round-trip the original host table name and any dummy partition/column details back to TMDL/TMSL.
- Avoid warning in a way that implies the measures are unsupported when only the table-as-dataset mapping is unsupported.
In short: exclude the blank table as a dataset if needed; do not exclude its measures as metrics.
Suggested direction (non-prescriptive)
Possible approaches:
-
Measure extraction before/without table export eligibility
Convert measures from all tables (or from tables excluded only for “not a dataset” reasons), while still stashing excluded table shells for round-trip.
-
Special-case measure-only / blank host tables
Detect hosts whose calculated partition is a dummy blank row (or tables with measures but no real data columns) and treat them as measure containers rather than as calculated datasets to drop entirely.
-
Document the limitation if intentional
If the current behavior is deliberate, document that measures on calculated/blank tables are stash-only and not portable metrics, and call out the impact on common Fabric modeling patterns.
Acceptance criteria (draft)
Summary
When importing a Fabric / Power BI TMDL model, the Microsoft converter does not treat a common “blank” or measure-only table as a valid host for measures. TMDL allows tables that exist primarily to hold measures (often with no real business columns, or only a dummy calculated column/partition). Today those tables are classified as calculated tables, excluded from the Ossie model, and their measures are preserved only inside the Power BI
custom_extensionsstash—rather than being mapped to first-class Ossiemetrics.Background
In TMDL / tabular models it is valid and common to define a table whose purpose is organizational: hold measures in one place (for example a
*_Measurestable), without modeling it as a real dataset end users query for columns.A typical shape is:
TMDL allows this. Measure evaluation does not require the host table to be a normal imported fact/dimension table.
Current behavior
On TMDL → Ossie import (
convert_semantic_model_to_ossie):source.type == "calculated"), among other exclusion rules (private tables, calculation groups, auto date tables).semantic_model.datasets.measures—is written into the model-levelPOWER_BIcustom_extensionspayload underexcludedTables.metrics[].Observed warning pattern:
Illustrative TMDL (generic)
Illustrative Ossie outcome (generic)
Instead of:
the measure information is effectively only recoverable from the model stash, conceptually:
Round-trip may still preserve the Power BI objects via the stash, but the portable Ossie document does not surface those measures as metrics.
Why this is a problem
Expected behavior
More ideal import behavior would separate table exclusion from measure import:
datasetswhen appropriate (dummy calculated hosts, private tables, etc.), or represent measure-only hosts in a clearly documented way if Ossie gains a better home for them.metricswithdialect: DAX, preserving description/format metadata via metric-levelcustom_extensionsas already done for measures on normal tables.In short: exclude the blank table as a dataset if needed; do not exclude its measures as metrics.
Suggested direction (non-prescriptive)
Possible approaches:
Measure extraction before/without table export eligibility
Convert measures from all tables (or from tables excluded only for “not a dataset” reasons), while still stashing excluded table shells for round-trip.
Special-case measure-only / blank host tables
Detect hosts whose calculated partition is a dummy blank row (or tables with measures but no real data columns) and treat them as measure containers rather than as calculated datasets to drop entirely.
Document the limitation if intentional
If the current behavior is deliberate, document that measures on calculated/blank tables are stash-only and not portable metrics, and call out the impact on common Fabric modeling patterns.
Acceptance criteria (draft)
metricswith DAX expressions.