MySQL’s Invalid Dates + Power Query = No Effect Query Folding?!

, , ,
Results display showing 0001-01-01 value

You’re authoring in Power Query. You decide that rows with 0001-01-01 in a certain column should be removed, so you filter on the column, excluding 0001-01-01 values. After you apply your filter, nothing changes: the 0001-01-01 rows are still present. What is going on?

This issue bit me recently. Turns out, it’s due to a translation loss when bridging between the worlds of MySQL and Power Query.

Continue reading

Highlights from the New Power Query SDK!

, ,

Earlier this month, Microsoft announced a public preview of the new Power Query SDK! This is an exciting advancement for those engaged in the world of custom connector development! The initial goal is for the new SDK to achieve feature parity with the long since abandoned legacy SDK, then to keep going by adding additional features to the new SDK that enhance connector development.

Microsoft has provided several online resources related to the new SDK:

I thought it would be interesting to highlight a few of the feature additions and enhancements present in the current preview version (version 0.1.7).

Continue reading

Solved Mystery: Microsoft Gantt Chart for Power BI Rejects Some Drag and Drops

, ,
Screenshot of Gantt chart's field list

On a project recently, I wanted to use Microsoft’s Gantt chart visual for Microsoft Power BI. Try as I might, I couldn’t get the visual to accept an end date or duration. I could drag a column from the data model over to the field box for End Date or Duration but the field would not “drop” into the field box. Instead, when I’d let go of the mouse button, the box would stay empty.

I built a small test Power BI report + dataset from scratch, and the Gantt chart visual worked fine—no problems with configuring it by dragging and dropping fields.

Why wouldn’t this Gantt visual work with my existing Power BI report, but work just fine with the test report?

Continue reading

No Built-In Power Query Connector: Am I Stuck?

, ,

Uh oh! You’re using Microsoft Power BI or Excel and you’ve discovered that Power Query does not have a built-in connector for the data source you’re interested in consuming.

Question: What does this mean for you?

Answer:
(pick which of the below you think is most likely correct)

  • No go. You cannot access this data source from Power Query.
  • Custom connector. “Built-in connector” and “custom connector” sound like opposites. Either you may need to fork out a bit of $$ to get a custom connector created, or give up.
  • Something else. Hmm…what are the other options?

I’d suggest starting with “something else.” When Power Query doesn’t ship with a connector for your source of interest, there are a number of other options to consider.

Let’s take a journey through the main other options for directly connecting to a source from Power Query. We’ll order these into “stages” based on an approximation of the level of effort involved. Then, we’ll expand our scope and touch on several possibilities that involve using external tools or languages to provide the needed data to Power Query.

But first, the problem scenario….

Continue reading

Custom Connectors: Native Query Support

, , ,

You’ve built a custom connector—and it works great! But regardless of how good your query folding implementation is, likely there are times that a hand-crafted native query can beat it in performance and capability. So, in addition to supporting query folding, you’d like to give users the option of using native requests that they write with your connector.

In a nutshell, you’re hoping to enable something like:

let
  Source = MyConnector.DataSourceFunction("some-host"),
  Results = Value.NativeQuery(Source, "some native request goes here")
in
  Results

Is this possible? From Power Query’s perspective, at the technical level: Yes—and it is easy to pull off.

Continue reading

An Error’s Expression Stack: A “Journal” of the Locations It Propagates Through

, , ,

A Power Query mashup expression dies with an error. As the error propagates through your code, did you know that it sometimes collects a “journal” of the locations (e.g. line numbers) it passes through? This “expression stack,” as it’s called, can be used to help identify the troublemaking line of code.

An error’s expression stack is not automatically exposed in any user interface. Its hidden presence suggests that it may be a component supporting some past, present or planned UI functionality (perhaps it’s part of powering the “Go to Error” button?). Even though it is hidden, there may be cases where you find the location details it contains useful when debugging. Even if not, knowing about it is interesting Power Query trivia. 🙂

Continue reading

Custom Connectors: Introducing Table.ViewError & Terminal Errors

,

If a table view handler raises an error, Power Query’s default behavior is to suppress the error and instead perform the requested operation internally. In a nutshell, Power Query internally does whatever it was that the user requested, since the view was unable to do so.

But what if this isn’t the desired behavior—what if a view handler should stop an operation from taking place, so the user sees it dying with an error?

Continue reading

Custom Connectors: Populating Table.Schema

,

Table.Schema offers to expose a variety of details about a table’s columns. Your custom connector can leverage this functionality to give users easy access to column-specific details from the external data source about the tables they are fetching.

Table.Schema output

Say that external source allows users to create new columns and give them descriptions. Why not make these descriptions available from within Power Query by having them appear in Table.Schema‘s Description column? Perhaps the type system on the source is a bit different from Power Query’s. Table.Schema columns like NativeTypeName, NumericScale and NumericPrecision can be used to communicate relevant details to your users for reference purposes, enhancing their understanding of the data they’re pulling.

How?

The idea of exposing informative details about a source’s columns is great—but how do you provide this information in a way that Table.Schema will read it? The answer depends on which Table.Schema column you’re trying to populate.

While these techniques may primarily be of interest to custom connector developers, they’re valid to use from any M code—no connector required.

Continue reading

Zero Rows Can Bite (part 2): The Mysterious All-Null Row

, , ,

The table you fetch from a web API mysteriously contains an unexpected row with a null value in each column. You manually try the API using a tool like Postman or Insomnia and don’t find any all-null objects in the raw response. Where is this null table row coming from?

Zero rows (again!).

Previously, we dug into refreshes mysteriously dying with the complaint that “column ‘Column1’ of the table wasn’t found” even though no M code or data source schema changes had occurred. Upon investigation, we learned that an insufficiently in some fetch data M code results in it outputting zero columns when the web API returns no rows, which breaks later code that expects the presence of specific columns.

This time, zero rows is again the trigger condition, though it’s not zero rows altogether. Instead, it’s when a web API that returns paged responses returns a page containing no rows. Receiving back an empty page is a real-world possibility. For example, the last page of a response might contain zero rows because the rows that were to have been in it were deleted just moments ago, after the preceding page was fetched.

A common pattern for processing paged responses is to read the various pages into a list, then turn that list into a table, which is then expanded out into the appropriate rows and columns. However, the implementation of this flow sometimes leaves a corner case unaccounted for which leads to the all-null row being present. Unfortunately, such an oversight is present in Table.GenerateByPage (a function commonly used by custom connectors).

Continue reading