Refresh individual Tables using The Composite Model in PowerBI

in Dec 2020, PowerBI introduced a fundamental change to the architecture of the Product, now when you connect to an existing model you can enhanced it by adding your own data.

Personally I find this functionality extremely useful, for example, I had access to an Enterprise Data Model that contains Oracle Primavera Data, but it was not very useful alone, that data make sense for my use case only when I combined it with other sources, now it is possible.

To make this functionality possible the Product team add the option to connect to an Existing PowerBI Dataset using DirectQuery, it is not SQL but DAX instead, I think you should read this first, if you haven’t already.

In this blog, I am experimenting with a new scenario just by curiosity, not sure if useful at all, but fun !!!! In PowerBI by default when you refresh a dataset, all the tables will refresh, the only way to control that is using XMLA endpoint, which involve some coding and require a premium license (PPU works too).

The idea is simple, let’s say you have a model with 4 tables, and only 1 Table needs to be refreshed frequently.

– Create a new Model that contain only 1 Table, setup schedule refresh to how often you want to see the data updated

– Delete that Table from the existing model, and connect to it from the new Model using DirectQuery

The Table that refresh frequently can be even a Realtime dataset

Testing

Again, don’t read too much into it, it just to give you an indication, The Data is Power Generation every 5 minutes, it make sense only to update the data for the current Day, all previous data does not change, The visual will show the data for today and yesterday.

1- All Tables are imported

notice Settlementdate is a datetime field, the data is imported using incremental refresh.

and here is the Model

here is the result, 378 ms

2-History Imported, Today Data DirectQuery

when you do DirectQuery mode, the performance will depend on the modelling used, here the measure Mw will sum the values from the History Table and Today Table.

if we use settlementdate as an X axis, the results will return in 80 Seconds

Now using two Dimension Date and time instead of Settlementdate, the Performance is nearly the same as import 492 ms

I can’t find a way to make date and time as a continuous axis in the Visual

I noticed if you use the DirectQuery Table without using dimensions from other models, the performance is extremely fast.

Take Away

I am not going to pretend I am an expert in DAX optimization, and Probably I am doing one or two things wrong, and as always it depends on a lot of factors 🙂 but as a rule of thumb:

DirectQuery on Dataset does not like Dimension with High cardinality

Import Model will be always more performant and tolerant to bad modelling

Data Modelling is very important, now it become even more critical

PowerBI Import mode is so fast and Powerful that even bad written DAX and poor Data Modelling will Just works, DirectQuery Mode on PowerBI Dataset will open all kind of new scenarios that was not possible before, but you have to be more careful about your modelling.

Building a Modern Data Stack using BigQuery, Dataform and PowerBI

Google cloud has bought recently Dataform and made it available for free, although I  play it with it before, Now I thought it is a good time to use it more seriously, this is not a review but my own experience as a data analyst who is more comfortable with Microsoft self-service data tools and  does not use SQL in day to day work.

I have an existing data pipeline in BigQuery, the data is loaded using python and there are schedule Queries using python and BigQuery native scheduler, although the whole thing worked very well for the last 15 months, I would not say working with multiple views and table was a pleasant experience, to be honest,  Because I was afraid to break something, I have not touch it much,  everything change since I start using Dataform to manage it

What Dataform did ( and I imagine dbt too)  is to implement some very simple functionalities that make the whole work flow extremely easy to manage, so you write your SQL code in Dataform, Dependencies between Tables are auto generated , and when you click run, it will build those Tables and views in BigQuery

I think showing a general overview of what I did, hopefully give you a sense of the Big picture

1- Define your Source Tables

Here is the representation in Dataform

for Example The Table “DREGION”, you write this code

config {
  type: "declaration",
  schema: "aemodataset",
  name: "DREGION",
  description: "Price very 5 minute, history"
}

you repeated the same for all the source Tables

and here is the View in the dependency trees

2- Remove hard coded refrence to Tables in SQL Queries

let’s say you have an existing view

SELECT
   *
 FROM
   xxxxxx.aemodataset.rooftoptoday

instead of hard coding the table, you change it to this

config {
   type: "view",
   schema: "PowerBI",
   tags: ["PowerBI"]
 }
 SELECT
   *
 FROM
   ${ref("rooftoptoday")}

This format is called SQLX, as you can see it is still SQL but they added some new functionalities, in the config, you define if it is a table or a view, in which dataset it will be located and tag ( will be useful later for schedule refresh)

Now, repeated this for all your tables and you get this beautiful dependency tree

3- Schedule Queries

And that’s that where the magic is, when you schedule a Query, you have an option to schedule all dependant tables, for example, I setup a daily refresh for the Table “UNITARCHIVE” , the two Tables “archive_view” and “revenue” will be run in Sequence without me writing any extra code

The Dataform project is published here github, it is really nice to see the history of all the changes made so easy with the integration of version controls

4- Here is the final Views in BigQuery

I think it is a good practise to always expose only Views to PowerBI, as you can change the logic later without breaking the connection to PowerBI

5-Connect PowerBI to BigQuery

PowerBI Connect to BigQuery using incremental refresh to reduce the time required to update, it is pretty trivial to setup.

Although the data changes every 5 minutes, I am using PowerBI PRO license which is limited to 8 refresh/Day, if Premium per user turn out to have a reasonable price, I will upgrade 🙂

hopefully in 2021 we will have the option to serve PowerBI using BI Engine, as Currently using DirectQuery from BigQuery can be expensive very Quickly if you have a lot of usage, Obviously if you are on a flat rate, it is not a problem.

to clarify, BigQuery is very cost effective, actually the current pipeline cost me less than 2 $/Month, you have just to be careful with PowerBI and use only import mode, PowerBI is very chatty when used in live mode, it simply generate two much SQL Queries.

6-Semantic Model in PowerBI

Dataform Data model are not meant to replace a semantic model, all Dataform do is taking raw tables and generating reporting tables that can be consumed by a BI tool (to clarify, BigQuery is generating the views and tables, Dataform just manage the SQL code, and schedule refresh, but the compute is done by the DB).

For a simple scenario, some flat tables is all you need (in Fact I am using Google Data Studio too for this example), but anything slightly complex , you need a semantic model on top of it, here I am using PowerBI to host the semantic model.

I would have loved to test Looker semantic model, But currently you need to call a sales department to schedule a demo which I am not really interested in doing.

7- Final Reports

Here is the final reports, as the data is public I am using publish to web

what I really like about the dependency tree, it gives visual clues to redundant logic, it gave me the confidence to simplify my workflow and when I delete or change a table names, automatically it raise an errors that a dependency will be out of sync

I keep reading about how ELT will be the next big thing, and to be honest I never bought the concept, but with Dataform, I can see myself writing very complex workflow using SQL.

Drill Down to another page in Google Data Studio, the easy way

I have blogged already how to drill down to another page using Parameter, today, I find another approach, it is extremely easy, and a bit embarrassed why I have not thought about before !!!

I will be using administrative division of Algeria as an example, see the report here, please notice the pattern is not only for maps, personally I use drill down to another page extensively with finance reports, for example drilling down by Project, vendor, user etc

1- Create a map at the region Level

2- Add a new empty tab

3- Make the Map at the report level

4-make sure apply filter is on

5- in the second tab , hide the map either using send to back or add a big rectangle

6- add a new map at the city level

7- add a new button to navigate between page 1 and 2

basically when you create a report level map, the selection from page 1 get synchronized to page 2 , then the hidden map in page 2 will filter the map at the city level.

Dynamic Weekend using Parameter in PowerBI

I had a perfectly Working PowerBI report the last 7 Months , The data is refreshed daily, but we need to see the weekly Quantity basically on a rolling basis of the last 7 days.

When the data refresh, a calculated column generate a new weekly grouping based on the latest update from a Fact Table “Quantity Installed”, see example here

weekend.JPG

Everything Worked well, till someone asked if he can filter previous days, let’s say the report is Updated Monday, but he want to see the Data only till the previous Thursday , which is the official Cut off for the Client reporting.

Obviously it is easy just filter the data, but visually it is annoying as the weekend date is still Monday, calculated column change only when your refresh a report , Then they are fixed.

To show an example, this report show the total fatalities due to COVID19 per Week, The Cut off is 03/11/2020 which is a Tuesday, the weekly calendar is based on Tuesday as the end of the week

Now if you filter the data to the Previous Friday, the Weekend do not change, hence you get the impression that the total number for the Current week are going down which is not correct.

So, I asked in PowerBI forum how to do that, and Brian Maher solution is as columns do not change, we need to change the DAX,see link to the original solution

“The measure below checks to see if our date on the X-axis is the same day of the week as your slicer. If not it returns BLANK( ), if it is the same day of week, it sums the qty for the previous 7 days”

 Qty at 'week end' =
 VAR SelectedSlicerDate =
     SELECTEDVALUE ( 'Slicer Dates'[Date] )
 VAR ThisDateOnAxis =
     SELECTEDVALUE ( 'Calendar'[Date] )
 RETURN
     IF (
         WEEKDAY ( SelectedSlicerDate ) <> WEEKDAY ( ThisDateOnAxis ),
         BLANK (),
         CALCULATE (
             SUM ( 'Data Table'[qty] ),
             DATESBETWEEN ( 'Calendar'[Date], ThisDateOnAxis - 6, ThisDateOnAxis )
         )
     )

It is basically using a well know technique in DAX, show all the dimension value then anything with BLANK() result will be filtered out.

The DAX works perfectly, and solved the user request but , In my real case I had a lot of measures, changing all of them and risking introducing regression for a perfectly Working Data Model just for this small request was not worth it.

All I wanted is somehow make the column Weekend Dynamic at runtime, which was not possible till …… October 2020, we do have a new option, we can finally change the dimension dynamically and keep the DAX simple !!!!

if you have not heard about the New Parameter, maybe a good start is here.

My first attempt was to get the Day of the week in PowerQuery, but unfortunately Query Folding stopped Working and to be honest there is no clear way to know what’s supported or not as it is data Source specific, here I am using BigQuery.

Instead I create a simple calendar table with a column Day and 7 columns with all the possible week end ( Saturday, Sunday etc)

and then Create a new Parameter, with a default Day Thursday

Then Created a new Column “DynamicWeek” using this formula

I think we can agree the formula is trivial , a simple if then else

In order to make the parameter Dynamic, we create a new disconnected Table (not connected to any other Tables in the Model)

Then we Bind the Value of the Column Day to the Parameter

When the User changed the value of the disconnected Table using a Slicer

The Value get passed to the Parameter which Change the Value of the Column “Dynamic Parameter”

And here is the result

Update

a couple of hours after I published this blog, I got an idea that actually did Work.

Query folding does not work with the function Day of the Week, but Text.Middle did fold indeed, so all I had to do is create a new Disconnected Table like this

the same approach add a calculated column in the calendar Table

Just to be fancy, in the parameter, I used a Query that return always the latest date as a default value

and View of the Data Model

Created a new Measure that use the Disconnected Table as a filter Cut off, so the date get filtered

Death_cutoff = Var Sum_=sum(covid19new[daily_deaths])
return if (min(MstDates[Date])>SELECTEDVALUE(MstDates_Table_Cutoff[date]),BLANK(),Sum_)

I imagine you can search the date text and see if it is the end of the Month and generate Monthly calendar for example, a lot of flexibility.

notice here, because the Date Table is DirectQuery ( the fact and the parameter selection table are import) at least when using BigQuery the response time for the first select is around 3 seconds, but when you do the same selection, it become instantaneous as PowerBI cache the query result.

Now the Exciting part is which we don’t have yet, but apparently is coming next year at least for SnowflakeDB and Redshift, we will be able to write Custom SQL Query with Parameters in DirectQuery Mode, and then basically we will have finally “Dynamic Calculated Column“, ok if we have them in Import Mode, it is even better but let’s not get too Excited 🙂

DAX is extremely versatile , combine that with Dynamic column and we have a very powerful new tool, the future is exciting.