Power BI Project: the guts of it
I always work in .pbip files.
Below is an abbreviated file structure of a .pbip file (I am only including the ones that are relevant, i.e. the ones we can change or extract meaningful information from).
$projectname
|_$projectname.Report
|_StaticResources
|_report.json
|_definition.pbir
|_$projectname.SemanticModel
|_model.bim
|_$projectname.pbip
These files are important, and all of them are .json files (though not all of their extensions say so):
model.bim
report.json
$projectname.pbip
definition.pbir
model.bim
and report.json
deserve their own articles, by themselves, so their inclusion here will be brief.
model.bim
This contains everything to do with data and transformations in a Power BI file. This includes:
- all Power Query scripts
- everything in DAX, including calculated columns, calculation groups, and measures
- relationships between tables
- columns and data types
report.json
This file contains all of the metadata to do with what you see on the screen. This includes:
- all of the pages and their properties
- all of the visuals and their properties, including what data they are connected to
report.json
is directly transplantable from one .pbip folder to another. This means that you can copy a report.json
from one .pbip folder to another, and at the very least, Power BI will open it without complaints (whether or not your report matches the data model is another matter).
.pbip file
This file sits at the "head" of the project. This is the file that you double-click on to open in Power BI. It points directly to the folder $project.Report
, which is how it knows what to display on the screen. The $projectname.Report
folder contains definition.pbir
, which points to the semantic model, which is how it knows what numbers to pull in, and where from.
The filename of this file dictates what it will be called when it is published up to a workspace in Power BI Service.
$projectname.pbip
looks like this:
{
"version": "1.0",
"artifacts": [ { "report": { "path": "$projectname.Report" } } ],
"settings": { "enableAutoRecovery": true }
}
.pbir file
definition.pbir
basically points to the semantic data model, and can look two different ways.
Local semantic model (the normal way)
The first is if the semantic model is available locally (i.e. if the .pbip file came from a semantic model .pbix file). The property datasetReference.byPath.path
points to a local location.
{
"version": "4.0",
"datasetReference": {
"byPath": { "path": "../$projectname.SemanticModel" },
"byConnection": null
}
}
Online semantic model
The second is if the report is connected to a semantic model in Power BI Service (i.e. if it came from a report-only .pbix file). The property datasetReference.byConnection
contains a whole object that tells Power BI how to connect to the semantic model online.
For all reports that refer to the same semantic data model, the definition.pbir
file is identical, meaning that it can be copied from one report to another.
The parts to pay attention to are the following:
- In
connectionString
, the part that comes after "Initial Catalog". This is the name of the semantic model, as it is named in the workspace.- If you're wondering how to target that part using regex, it's like this:
(?<=Catalog=").*(?=")
.
- If you're wondering how to target that part using regex, it's like this:
- The property
pbiModelDatabaseName
. This is crucial for connecting a semantic data model online. The only way I know is the long way, that is:- Download a report-only file from the workspace
- Save it as a .pbip
- Crack open the .pbir file and get it
I've found in one situation where the .pbip would not recognise the workspace data set, and was only resolved when I created a different workspace with a different name (incidentally, the new workspace had no spaces in the name).
{
"version": "4.0",
"datasetReference": {
"byPath": null,
"byConnection": {
"connectionString": "Data Source=powerbi://api.powerbi.com/v1.0/<guid>/<workspacename>;Initial Catalog=\"<semanticmodelname>\";Access Mode=readonly;Integrated Security=ClaimsToken",
"pbiServiceModelId": null,
"pbiModelVirtualServerName": "sobe_wowvirtualserver",
"pbiModelDatabaseName": "<semanticmodelguid>",
"name": "EntityDataSource",
"connectionType": "pbiServiceXmlaStyleLive"
}
}
}
Switching between the two
Switching between the two is almost as simple as substituting one .pbir file for another.
The one thing to note with the local data file is that the path
property is a relative path, so be careful with how that is written out