The data model (PBIP / TMDL)¶
This note explains the Power BI semantic model that lives in powerbi/ — what it
contains and why it is built the way it is. It is written for someone meeting
these ideas for the first time.
Why the model is stored as text¶
Instead of a binary .pbix, this project uses the PBIP save format. The data
model is written in TMDL (Tabular Model Definition Language) — readable text
files, one per table. Benefits:
- every change is visible in a git diff (see ADR 0002);
- the model can be authored and reviewed as code;
- it demonstrates a modern, engineering-grade Power BI workflow.
A TMDL table file looks like this (abbreviated):
table dim_customers
measure 'Distinct Customers' = DISTINCTCOUNT('dim_customers'[customer_unique_id])
column customer_id
dataType: string
isKey
partition dim_customers = m
mode: import
source = // Power Query (M) that reads dim_customers.csv
Three ideas in one file: columns (the fields), a partition (an M query that loads the data), and measures (DAX calculations).
The star schema¶
The model is a star schema: dimension tables describe things, fact tables record events, and facts point at dimensions through relationships.
| Dimensions (who/what/when) | Facts (events/measures) |
|---|---|
dim_customers, dim_products, dim_sellers, dim_date |
fact_order_items, fact_orders, fact_payments, fact_reviews |
Each fact carries customer_id and order_purchase_date, so it links directly to
dim_customers and dim_date. There are 10 relationships, all many-to-one
(fact → dimension) with single-direction filtering. See the
data dictionary for every column.
flowchart TD
C[dim_customers] --- OI[fact_order_items]
P[dim_products] --- OI
S[dim_sellers] --- OI
D[dim_date] --- OI
C --- O[fact_orders]
D --- O
C --- PM[fact_payments]
C --- R[fact_reviews]
The DAX measures¶
Measures are calculations evaluated in the filter context of a visual. The model ships with a starter set, for example:
| Measure | Definition (in words) |
|---|---|
Revenue (R$) |
Sum of item prices |
Orders with Items |
Distinct count of order ids |
Avg Order Value (R$) |
Revenue ÷ orders |
On-Time Delivery % |
Average of the 1/0 is_on_time flag |
Avg Delivery Days |
Average actual delivery time |
Avg Review Score |
Average 1–5 rating |
Distinct Customers |
Distinct count of customer_unique_id |
How the data is loaded¶
Each table's partition is a Power Query (M) script that reads its CSV from the
folder given by the DataFolder parameter. That parameter defaults to a local
absolute path; anyone else must point it at their own data/processed folder
(Transform data → Edit parameters in Power BI Desktop).
Opening the project — the one-time setup¶
Power BI Desktop needs three preview features enabled to open a PBIP/TMDL/PBIR project (File → Options and settings → Options → Preview features):
- Power BI Project (.pbip) save option
- Store semantic model using TMDL format
- Store reports using enhanced metadata format (PBIR)
Restart Desktop, then open powerbi/OlistAnalytics.pbip, adjust DataFolder if
needed, and refresh. The report page (Overview) is currently empty — building
its visuals is the next phase.