Scaffolding
0 0 About
Scaffolding · Lesson 4 of 7

Generators,
not hand-writing

Nobody laid these bricks one by one. Three scripts read the specs, the DAX files and the seed, and wrote the report's files. That made the build repeatable, and every change easy to see.
Have the report open. The lessons point at real pages and tiles. The .pbix opens in Power BI Desktop; the PDF works on any device, but things like View as and the i buttons need Desktop.
00

Three scripts write the report

The report is a : hundreds of plain-text files. They weren't typed by hand. Three s wrote them, one per layer:

gen_model.pyThe : the parameter, three query layers, 32 tables, 53 relationships, sort orders, the date table.
gen_measures.py156 measures copied from the DAX files, the 41 basis measures and the four roles.
gen_pages.pyThe report pages, every visual shaped like its example in the seed.
Open gen_model.py on GitHub

Predict first: The pages spec changes: one tile moves. Why is a script better than editing the files by hand?

01

Run order matters

The top of gen_model.py carries a warning in capitals:

RUN ORDER MATTERS. This script rewrites _Measures.tmdl as an empty table, so running it on its own undoes phase 2. Run gen_measures.py straight afterwards to put the 156 measures and the four roles back.

Predict first: You run gen_model.py on its own and stop there. What happens to the measures?

02

Same input, same output

Every table, column and measure in a Power BI model has a , a unique id. shows every line that changes between runs. A generator could make a new random one each run. These don't: each tag is worked out from the item's name, so a rerun writes the same tag again.

Safe to re-run: the lineage tags are uuid5 values taken from the measure names, so the output does not change.

Predict first: Why does it matter that a rerun writes byte-for-byte the same files?

03

Desktop wins on format

The generators don't write files in their own style. They copy 's, down to the order of properties and the blank line at the end. The comment in gen_model.py says where that came from:

The layout here is Power BI Desktop's own, taken from what Desktop wrote when the phase 1 project was opened and saved. Do not tidy any of that: Desktop wins on format.

Predict first: A generator writes a column's properties in a tidy order. Desktop saves them in a different order. Which should the generator follow?

04

Three files that still differ

Copying Desktop's format gets almost everything to match. The kit's README records the three files that still don't, because Desktop rewrote them when the finished report was saved:

model.tmdl one blank line more DimMeasureBasis.tmdl the TileStatus column in a different place _Measures.tmdl measure bodies one tab less indented The content is the same: Desktop wins on format.

Predict first: Should you rerun the generators to make those three files match again?

05

Never against the real folder without a yes

Because a generator rewrites files wholesale, the brief puts running them against report/ on its "never without asking" list. To check what a run would do, use a . gen_pages.py even has a switch for it:

With --out, it copies report/Report.Report to a folder and writes there instead, leaving report untouched: that is how a run is checked against git.

Predict first: You want to know whether the generators still reproduce the report. What's the safe way?

06

Built, not hand-laid

The walls went up from the plans. Next lesson: the order they went up in, and where the build stopped to be checked.

Generate from the spec. Same input, same output. Copy Desktop's format, and write down the few places it still differs.

Try a generator in a copy before you let it near the real folder.