Forum Discussion

RossS's avatar
RossS
Icon for Helper II rankHelper II
1 month ago

Configuring Incremental & Scheduled Refresh

I'm currently preparing for a change in our system going from on premises to cloud based. I will be using incremental and scheduled refresh shortly so am setting everything up now, ready for the upgrade.

 

I'm trying to understand the date/time format that is required in a table. The Microsoft documentation states

'The data type of the RangeStart and RangeEnd parameters must be of date/time data type regardless of the data type of the date column. However, for many data sources, tables don't have a column of date/time data type but instead have a date column of integer surrogate keys in the form of yyyymmdd. You typically can't convert these integer surrogate keys to the Date/Time data type because the result would be a non-folding query expression'

 

My tables have date columns which look like the below:

06/08/2026

I can however change these in Power Query to be date/time by clicking the drop down arrow. This now shows the data as below:

01/08/2024 00:00:00

 

Is this sufficient for allowing incremental and scheduled refreshes or will this break query folding?

10 Replies

  • Yes, that setup is fine. The warning in the docs applies specifically to integer surrogate keys like 20240801, not to real date columns like the one you have. Converting a Date column to Date/Time in Power Query is the standard supported path for incremental refresh and normally folds against relational sources such as SQL Server, Azure SQL, or Fabric Warehouse.

     

    To confirm folding on your specific source, right-click the last step in Power Query and choose View Native Query. If you can see the underlying SQL, folding is still intact. Then apply the RangeStart and RangeEnd filter with Table.SelectRows and check View Native Query again to confirm the filter pushes down to the source.

     

    If this helped, a thumbs up and accepting the solution would be appreciated.

     

    Best,
    Shai Karmani

  • ShahRukhSameer's avatar
    ShahRukhSameer
    Icon for Continued Contributor rankContinued Contributor

    Hi RossS​,

    Your date column already looks much closer to what Incremental Refresh expects.

    The important thing isn't just that the column displays as a Date/Time in Power Query. The key requirement is that the filtering step using RangeStart and RangeEnd still folds back to the source.

    A simple way to verify this is:

    1. Create the RangeStart and RangeEnd parameters as Date/Time.
    2. Apply your incremental refresh filter using those parameters.
    3. Right-click the filtered step in Power Query and check "View Native Query" (if your source supports it).

    If View Native Query is still available after applying the filter, that's a good sign that query folding is being preserved.

    One thing to be careful about is where the Date/Time conversion happens. If your source column is already a true date or datetime type in the database, changing the type in Power Query is usually fine. However, if Power Query is having to perform a complex conversion on every row before applying the RangeStart/RangeEnd filter, folding can break and incremental refresh may not work efficiently.

    My recommendation would be to validate query folding after the filter step rather than relying solely on the displayed format. If folding is preserved, you're generally good to proceed with incremental refresh and scheduled refresh configuration.

  • Hi RossS 

    If you go to official microsoft documentation.they have provided a mechanism to convert datetime to any datekey format.

    https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-overview 

    below is the example i am talking about.

    let
      Source = Sql.Database("dwdev02","AdventureWorksDW2017"),
      Data  = Source{[Schema="dbo",Item="FactInternetSales"]}[Data],
      #"Filtered Rows" = Table.SelectRows(Data, each [OrderDateKey] >= Int32.From(DateTime.ToText(RangeStart,[Format="yyyyMMdd"]))),
      #"Filtered Rows1" = Table.SelectRows(#"Filtered Rows", each [OrderDateKey] < Int32.From(DateTime.ToText(RangeEnd,[Format="yyyyMMdd"])))
      
    in
      #"Filtered Rows1"

    Like INt32 converts it to numeric for numericdate column.you can convert datetime column to date like below.

    let
      Source = Sql.Database("dwdev02","AdventureWorksDW2017"),
      Data  = Source{[Schema="dbo",Item="FactInternetSales"]}[Data],
      #"Filtered Rows" = Table.SelectRows(Data, each [OrderDate] >= RangeStart),
      #"Filtered Rows1" = Table.SelectRows(#"Filtered Rows", each [OrderDate] < RangeEnd)
    in
      #"Filtered Rows1"

    Please give kudos or mark it as solution once confirmed.

    so RangeStart and RangeEnd datatype remains datetime.

  • v-saisrao-msft's avatar
    v-saisrao-msft
    Icon for Community Support rankCommunity Support

    Hi RossS​,

    Checking in to see if your issue has been resolved. let us know if you still need any assistance.

    Thank you.

  • That's fine. The warning in the docs is about converting integer surrogate keys (yyyymmdd) to date/time, which breaks folding because it needs a full table scan to reinterpret the integers. Your column is already a proper date column, so converting it to date/time is a normal type change that folds against most sources (SQL Server, Synapse, etc.)

  • I've added steps in Power Query to limit my date:

    = Table.SelectRows(Item_Ledger_Entries_Excel_table, each DateTime.From([Posting_Date]) >= RangeStart and DateTime.From([Posting_Date]) < RangeEnd)

    I've also set Incremental Refresh policies for the table, archiving data to 2 years and incrementally refresh data starting 3 days ago.

    Refresh in Power BI desktop works fine, I publish to service, refresh and it appears to be loading but fails.:

    Data source errorDataSource.Error: OData: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.. Microsoft.Data.Mashup.ValueError.DataSourceKind = OData. DataSourcePath = https://api.businesscentral.dynamics.com/v2.0/3243243fsdfdsfsd/Production/ODataV4/Company('CompanyName')/ItemLedgerEntries. . The exception was raised by the IDataReader interface. Please review the error message and provider documentation for further information and corrective action.

    Any idea where to go from here?

    • ShivekMaharaj's avatar
      ShivekMaharaj
      Icon for Memorable Member rankMemorable Member

      Hi RossS​,

      The new error changes the troubleshooting direction a little. I don't think your Date/Time format is the main issue now.

      Your RangeStart and RangeEnd setup is conceptually correct, but the first incremental refresh in the Power BI service is different from the refresh you see in Desktop. Microsoft explains in its incremental refresh troubleshooting guidance that the service creates and queries multiple partitions during the initial refresh. If the date filter is not being pushed back to the source, each partition can end up requesting far more data than intended.

      The first thing I would therefore verify is whether your OData request is actually receiving the RangeStart / RangeEnd filter.

      Since Posting_Date is already typed as Date/Time, I would simplify your filter to:

      each [Posting_Date] >= RangeStart and [Posting_Date] < RangeEnd

      rather than applying DateTime.From() to every row. I wouldn't say the conversion is definitely causing the failure, but if the column is already Date/Time it is unnecessary and removing it keeps the folding expression as simple as possible.

      For OData sources, Microsoft's Query Diagnostics guidance is useful here because it lets you inspect the actual request Power Query sends to the OData endpoint. I would check that the resulting request contains an OData $filter corresponding to your Posting_Date, RangeStart and RangeEnd conditions.

      That is particularly relevant in your case because the failing URL is a Business Central OData V4 endpoint. Microsoft documents that Business Central web services have operational limits and can throttle or time out expensive requests. If the incremental partitions are each causing a broad scan instead of a filtered OData request, the service refresh could put considerably more pressure on the endpoint than your Desktop test.

      So I would go in this order:

      1. Remove the unnecessary DateTime.From() if Posting_Date is already Date/Time.
      2. Use Query Diagnostics to confirm the generated OData request contains the expected date $filter.
      3. If folding is confirmed, test a copy of the model with a much smaller historical archive period to see whether the initial two-year load is what triggers the failure.
      4. If that smaller initial refresh succeeds, the issue is more likely related to the volume/concurrency of the initial partition processing rather than the Date/Time configuration itself.
      5. If even a small filtered refresh fails, I would then investigate the Business Central OData request/timeout behaviour and the detailed refresh diagnostics.


      So I wouldn't change the Date/Time design yet. I would first prove that each incremental partition is reaching Business Central as a properly filtered OData request.

      AI-assisted drafting: AI was used to help structure and phrase this response. I reviewed and validated the technical content before posting.

  • ShivekMaharaj's avatar
    ShivekMaharaj
    Icon for Memorable Member rankMemorable Member

    Hi RossS​,

    If that column is genuinely typed as Date/Time in Power Query, then a value such as 01/08/2024 00:00:00 is fine. The visible formatting itself does not prevent incremental refresh.

    The important part is that RangeStart and RangeEnd are created as Date/Time parameters and that the table is filtered using those parameters. Microsoft's incremental refresh configuration guidance only requires the DateTime-to-integer conversion when the source stores the date as an integer surrogate key such as 20240801.

    I would also verify that the filter step still folds back to the source. If View Native Query remains available after applying the RangeStart/RangeEnd filter, that is a good sign the source can handle the partition filtering efficiently.

    So based on the example you showed, I would not convert that Date/Time column to an integer unless the underlying source actually uses an integer date key.

    AI-assisted drafting: AI was used to help structure and phrase this response. I reviewed and validated the technical content before posting.

  • It's quite confusing when multiple people respond to my question, saying similar things but not reading what other people have written.

    I will check suggestions once our system has been moved to SAS next month and reply then.