Zaawansowane odświeżanie przyrostowe i dane w czasie rzeczywistym za pomocą punktu końcowego XMLA

Modele semantyczne w pojemności Premium z włączonym punktem końcowym XMLA dla operacji odczytu/zapisu umożliwiają bardziej zaawansowane odświeżanie, zarządzanie partycjami i tylko wdrożenia metadanych za pośrednictwem narzędzia, skryptów i obsługi interfejsu API. Ponadto operacje odświeżania za pośrednictwem punktu końcowego XMLA nie są ograniczone do 48 odświeżeń dziennie, a zaplanowany limit czasu odświeżania nie jest nakładany.

Partycje

Partycje tabeli modelu semantycznego nie są widoczne i nie można nimi zarządzać przy użyciu programu Power BI Desktop ani usługa Power BI. W przypadku modeli w obszarze roboczym przypisanym do pojemności Premium partycje można zarządzać za pośrednictwem punktu końcowego XMLA przy użyciu narzędzi, takich jak SQL Server Management Studio (SSMS), edytor tabelaryczny typu open source, skrypt z językiem TMSL (Tabular Model Scripting Language) i programowo za pomocą tabelarycznego modelu obiektów (TOM).

Po pierwszym opublikowaniu modelu w usługa Power BI każda tabela w nowym modelu ma jedną partycję. W przypadku tabel bez zasad odświeżania przyrostowego jedna partycja zawiera wszystkie wiersze danych dla tej tabeli, chyba że zastosowano filtry. W przypadku tabel z zasadami odświeżania przyrostowego istnieje tylko jedna partycja początkowa, ponieważ usługa Power BI nie zastosowała jeszcze zasad. Partycję początkową można skonfigurować w programie Power BI Desktop podczas definiowania filtru zakresu dat/godzin dla tabeli na RangeStart podstawie parametrów i RangeEnd oraz innych filtrów zastosowanych w Edytor Power Query. Ta początkowa partycja zawiera tylko te wiersze danych, które spełniają kryteria filtrowania.

Podczas pierwszej operacji odświeżania tabele bez zasad odświeżania przyrostowego odświeżają wszystkie wiersze zawarte w domyślnej pojedynczej partycji tej tabeli. W przypadku tabel z zasadami odświeżania przyrostowego odświeżanie odświeżanie i partycje historyczne są tworzone automatycznie, a wiersze są ładowane do nich zgodnie z datą/godziną każdego wiersza. Jeśli zasady odświeżania przyrostowego obejmują pobieranie danych w czasie rzeczywistym, usługa Power BI dodaje również partycję DirectQuery do tabeli.

Ta pierwsza operacja odświeżania może zająć sporo czasu w zależności od ilości danych, które należy załadować ze źródła danych. Złożoność modelu może być również istotnym czynnikiem, ponieważ operacje odświeżania muszą wykonywać więcej operacji przetwarzania i ponownego obliczania. Tę operację można uruchomić. Aby uzyskać więcej informacji, zobacz Zapobieganie przekroczeniom limitu czasu podczas początkowego pełnego odświeżania.

Partycje są tworzone dla i nazwane według stopnia szczegółowości okresu: Lata, kwartały, miesiące i dni. Najnowsze partycje, partycje odświeżania , zawierają wiersze w okresie odświeżania określonym w zasadach. Partycje historyczne zawierają wiersze według pełnego okresu do okresu odświeżania. Jeśli włączono czas rzeczywisty, partycja DirectQuery pobiera wszelkie zmiany danych, które wystąpiły po dacie zakończenia okresu odświeżania. Stopień szczegółowości odświeżania i partycji historycznych zależy od okresów odświeżania i historycznego (sklepu) wybieranego podczas definiowania zasad.

Jeśli na przykład bieżąca data to 2 lutego 2021 r., a tabela FactInternetSales w źródle danych zawiera wiersze do dnia dzisiejszego, jeśli nasze zasady określają, aby uwzględnić zmiany w czasie rzeczywistym, odśwież wiersze w ciągu ostatniego dnia okresu odświeżania i zapisać wiersze w ciągu ostatnich trzech lat w okresie historycznym. Następnie przy pierwszej operacji odświeżania zostanie utworzona partycja DirectQuery dla zmian w przyszłości, zostanie utworzona nowa partycja importu dla dzisiejszych wierszy, partycja historyczna zostanie utworzona dla wczoraj, cały dzień, 1 lutego 2021 r. Partycja historyczna jest tworzona dla poprzedniego okresu całego miesiąca (styczeń 2021 r.), tworzona jest partycja historyczna dla poprzedniego okresu całego roku (2020), a partycje historyczne dla całych okresów roku 2019 i 2018 są tworzone. Nie utworzono żadnych partycji całych kwartałów, ponieważ nie ukończyliśmy jeszcze pierwszego pełnego kwartału 2021 roku.

Diagram shows the partition naming granularity described in the text.

W przypadku każdej operacji odświeżania odświeżane są tylko partycje okresu odświeżania, a filtr daty partycji DirectQuery jest aktualizowany tak, aby zawierał tylko te zmiany, które występują po bieżącym okresie odświeżania. Nowa partycja odświeżania jest tworzona dla nowych wierszy z nową datą/godziną w zaktualizowanym okresie odświeżania, a istniejące wiersze z datą/godziną już w istniejących partycjach w okresie odświeżania są odświeżane aktualizacjami. Wiersze z datą/godziną starszą niż okres odświeżania nie są już odświeżane.

W miarę zamykania całych okresów partycje są scalane. Jeśli na przykład w zasadach zostanie określony okres odświeżania jednorazowego i trzyletni okres przechowywania historycznego, w pierwszym dniu miesiąca wszystkie partycje dni dla poprzedniego miesiąca zostaną scalone z partycją miesiąca miesięcznego. W pierwszym dniu nowego kwartału wszystkie trzy poprzednie partycje miesiąca są scalane w ćwierć partycji. W pierwszym dniu nowego roku wszystkie cztery partycje z poprzedniego kwartału są scalane w partycje roku.

Model zawsze zachowuje partycje dla całego historycznego okresu przechowywania oraz partycje całego okresu w górę przez bieżący okres odświeżania. W tym przykładzie pełne trzy lata danych historycznych są przechowywane w partycjach w latach 2018, 2019, 2020, a także partycje dla okresu miesiąca 2021Q101, okresu dnia 2021Q10201 i partycji okresu odświeżania bieżącego dnia. Ponieważ przykład przechowuje dane historyczne przez trzy lata, partycja z 2018 r. jest zachowywana do czasu pierwszego odświeżenia 1 stycznia 2022 r.

W przypadku odświeżania przyrostowego i danych czasu rzeczywistego usługa obsługuje zarządzanie partycjami na podstawie zasad. Mimo że usługa może obsługiwać wszystkie funkcje zarządzania partycjami, korzystając z narzędzi za pośrednictwem punktu końcowego XMLA, można selektywnie odświeżać partycje pojedynczo, sekwencyjnie lub równolegle.

Zarządzanie odświeżaniem za pomocą programu SQL Server Management Studio

Program SQL Server Management Studio (SSMS) może służyć do wyświetlania partycji utworzonych przez aplikację zasad odświeżania przyrostowego i zarządzania nimi. Korzystając z programu SSMS, można na przykład odświeżyć konkretną partycję historyczną, która nie przypada w okresie odświeżania przyrostowego, aby wykonać aktualizację z datą wsteczną bez konieczności odświeżania wszystkich danych historycznych. Program SSMS może być również używany podczas ładowania danych historycznych dla dużych modeli przez przyrostowe dodawanie/odświeżanie partycji historycznych w partiach.

Screenshot shows the Partitions window in SSMS.

Zastępowanie zachowania odświeżania przyrostowego

W programie SSMS masz również większą kontrolę nad sposobem wywoływania odświeżeń przy użyciu języka skryptowego modelu tabelarycznego i modelu obiektów tabelarycznych. Na przykład w programie SSMS w Eksplorator obiektów kliknij prawym przyciskiem myszy tabelę, a następnie wybierz opcję menu Przetwarzanie tabeli, a następnie wybierz przycisk Skrypt, aby wygenerować polecenie odświeżania TMSL.

Screenshot shows the Script button in Process Table dialog.

Te parametry mogą być używane z poleceniem odświeżania TMSL w celu zastąpienia domyślnego zachowania odświeżania przyrostowego:

  • applyRefreshPolicy. Jeśli tabela ma zdefiniowane zasady odświeżania przyrostowego, określ, applyRefreshPolicy czy zasady są stosowane, czy nie. Jeśli zasady nie są stosowane, pełna operacja procesu pozostawia definicje partycji bez zmian, a wszystkie partycje w tabeli zostaną w pełni odświeżone. Domyślna wartość to true.

  • effectiveDate. Jeśli są stosowane zasady odświeżania przyrostowego, należy znać bieżącą datę, aby określić zakresy okien krocznych dla okresów odświeżania przyrostowego i historycznych. Parametr effectiveDate umożliwia zastąpienie bieżącej daty. Ten parametr jest przydatny w przypadku testowania, pokazów i scenariuszy biznesowych, w których dane są odświeżane przyrostowo w przeszłości lub w przyszłości, na przykład budżety w przyszłości. Wartością domyślną jest data bieżąca.

{ 
  "refresh": {
    "type": "full",

    "applyRefreshPolicy": true,
    "effectiveDate": "12/31/2013",

    "objects": [
      {
        "database": "IR_AdventureWorks", 
        "table": "FactInternetSales" 
      }
    ]
  }
}

Aby dowiedzieć się więcej na temat zastępowania domyślnego zachowania odświeżania przyrostowego za pomocą języka TMSL, zobacz Odświeżanie polecenia.

Zapewnianie optymalnej wydajności

W przypadku każdej operacji odświeżania usługa Power BI może wysyłać zapytania inicjowania do źródła danych dla każdej partycji odświeżania przyrostowego. Możesz zwiększyć wydajność odświeżania przyrostowego, zmniejszając liczbę zapytań inicjacyjnych, zapewniając następującą konfigurację:

  • Tabela, dla której konfigurujesz odświeżanie przyrostowe, powinna pobierać dane z jednego źródła danych. Jeśli tabela pobiera dane z więcej niż jednego źródła danych, liczba zapytań wysyłanych przez usługę dla każdej operacji odświeżania jest mnożona przez liczbę źródeł danych, co potencjalnie zmniejsza wydajność odświeżania. Upewnij się, że zapytanie dotyczące tabeli odświeżania przyrostowego dotyczy pojedynczego źródła danych.
  • W przypadku rozwiązań z przyrostowym odświeżaniem partycji importu i danych w czasie rzeczywistym za pomocą zapytania bezpośredniego wszystkie partycje muszą wykonywać zapytania dotyczące danych z jednego źródła danych.
  • Jeśli wymagania dotyczące zabezpieczeń są dozwolone, ustaw ustawienie Poziom prywatności źródła danych na Wartość Organizacyjna lub Publiczna. Domyślnie poziom prywatności to Prywatny, jednak ten poziom może uniemożliwić wymianę danych z innymi źródłami chmury. Aby ustawić poziom prywatności, wybierz menu Więcej opcji, a następnie wybierz pozycję Ustawienia> Poświadczenie>źródła danych Edytuj poświadczenia>Ustawienia poziomu prywatności dla tego źródła danych. Jeśli poziom prywatności został ustawiony w modelu programu Power BI Desktop przed opublikowaniem w usłudze, nie zostanie przeniesiony do usługi podczas publikowania. Nadal musisz ustawić go w ustawieniach modelu semantycznego w usłudze. Aby dowiedzieć się więcej, zobacz Poziomy prywatności.
  • Jeśli używasz lokalnej bramy danych, upewnij się, że używasz wersji 3000.77.3 lub nowszej.

Zapobieganie przekroczeniom limitu czasu podczas początkowego pełnego odświeżania

Po opublikowaniu w usługa Power BI początkowa operacja pełnego odświeżania modelu tworzy partycje dla tabeli odświeżania przyrostowego, ładowania i przetwarzania danych historycznych przez cały okres zdefiniowany w zasadach odświeżania przyrostowego. W przypadku niektórych modeli, które ładują i przetwarzają duże ilości danych, czas, jaki trwa początkowa operacja odświeżania, może przekroczyć limit czasu odświeżania narzucony przez usługę lub limit czasu zapytania narzucony przez źródło danych.

Bootstrapping początkowej operacji odświeżania umożliwia usłudze tworzenie obiektów partycji dla tabeli odświeżania przyrostowego, ale nie ładowania i przetwarzania danych historycznych do żadnej z partycji. Program SSMS jest następnie używany do selektywnego przetwarzania partycji. W zależności od ilości danych do załadowania dla każdej partycji można przetwarzać poszczególne partycje sekwencyjnie lub w małych partiach, aby zmniejszyć potencjał co najmniej jednej z tych partycji, aby spowodować przekroczenie limitu czasu. Poniższe metody działają dla dowolnego źródła danych.

Stosowanie zasad odświeżania

Narzędzie Tabular Editor 2 typu open source umożliwia łatwe uruchomienie początkowej operacji odświeżania. Po opublikowaniu modelu z zasadami odświeżania przyrostowego zdefiniowanymi dla niego z programu Power BI Desktop do usługi połącz się z modelem przy użyciu punktu końcowego XMLA w trybie odczytu/zapisu. Uruchom polecenie Zastosuj zasady odświeżania w tabeli odświeżania przyrostowego. W przypadku zastosowania tylko zasad partycje są tworzone, ale żadne dane nie są do nich ładowane. Następnie połącz się z programem SSMS, aby odświeżyć partycje sekwencyjnie lub w partiach w celu załadowania i przetworzenia danych. Aby uzyskać więcej informacji, zobacz Odświeżanie przyrostowe w dokumentacji edytora tabelarycznego.

Screenshot show the Tabular Editor with Apply Refresh Policy selected.

Filtr Power Query dla pustych partycji

Przed opublikowaniem modelu w usłudze w Edytor Power Query dodaj kolejny filtr do ProductKey kolumny, która odfiltruje dowolną wartość inną niż 0 lub odfiltruj wszystkie dane z tabeli FactInternetSales.

Screenshot shows the Power Query Editor with code that filters out the product key.

Po wybraniu pozycji Zamknij i zastosuj w Edytor Power Query zdefiniowania zasad odświeżania przyrostowego i zapisania modelu model jest publikowany w usłudze. Z poziomu usługi początkowa operacja odświeżania jest uruchamiana w modelu. Partycje tabeli FactInternetSales są tworzone zgodnie z zasadami, ale żadne dane nie są ładowane i przetwarzane, ponieważ wszystkie dane są odfiltrowane.

Po zakończeniu początkowej operacji odświeżania w Edytor Power Query zostanie usunięty inny filtr w kolumnieProductKey. Po wybraniu pozycji Zamknij i zastosuj w Edytor Power Query i zapisaniu modelu model nie zostanie ponownie opublikowany. Jeśli model zostanie ponownie opublikowany, zastępuje ustawienia zasad odświeżania przyrostowego i wymusza pełne odświeżanie modelu po wykonaniu kolejnej operacji odświeżania z usługi. Zamiast tego przeprowadź wdrożenie metadanych tylko przy użyciu zestawu narzędzi do zarządzania cyklem życia aplikacji (ALM), który usuwa filtr w ProductKey kolumnie z modelu. Program SSMS może następnie służyć do selektywnego przetwarzania partycji. Gdy wszystkie partycje zostały w pełni przetworzone, które muszą obejmować ponowne obliczanie procesu na wszystkich partycjach, z programu SSMS, kolejne operacje odświeżania modelu z usługi odświeżają tylko partycje odświeżania przyrostowego.

Napiwek

Pamiętaj, aby zapoznać się z filmami wideo, blogami i nie tylko udostępnianymi przez społeczność ekspertów ds. analizy biznesowej w usłudze Power BI.

Aby dowiedzieć się więcej na temat przetwarzania tabel i partycji z programu SSMS, zobacz Process database, table, or partitions (Analysis Services). Aby dowiedzieć się więcej na temat przetwarzania modeli, tabel i partycji przy użyciu języka TMSL, zobacz Odświeżanie polecenia (TMSL).

Zapytania niestandardowe do wykrywania zmian danych

TMSL i TOM mogą służyć do zastępowania zachowania wykrytych zmian danych. Ta metoda może nie tylko służyć do uniknięcia utrwalania kolumny ostatniej aktualizacji w pamięci podręcznej, ale może włączyć scenariusze, w których konfiguracja lub tabela instrukcji jest przygotowywana przez procesy wyodrębniania, przekształcania i ładowania (ETL) na potrzeby flagowania tylko partycji, które muszą zostać odświeżone. Ta metoda może utworzyć bardziej wydajny proces odświeżania przyrostowego, w którym odświeżane są tylko wymagane okresy, niezależnie od tego, jak długo miały miejsce aktualizacje danych.

Element pollingExpression ma być lekkim wyrażeniem języka M lub nazwą innego zapytania języka M. Musi zwrócić wartość skalarną i zostanie wykonana dla każdej partycji. Jeśli zwrócona wartość różni się od tego, co miało miejsce podczas ostatniego odświeżania przyrostowego, partycja jest oflagowana do pełnego przetwarzania.

Poniższy przykład obejmuje wszystkie 120 miesięcy w okresie historycznym dla zmian wstecznych. Określenie 120 miesięcy zamiast 10 lat oznacza, że kompresja danych może nie być tak wydajna, ale nie trzeba odświeżać całego roku historycznego, co byłoby droższe, gdy miesiąc byłby wystarczający do zmiany wstecznej.

"refreshPolicy": {
    "policyType": "basic",
    "rollingWindowGranularity": "month",
    "rollingWindowPeriods": 120,
    "incrementalGranularity": "month",
    "incrementalPeriods": 120,
    "pollingExpression": "<M expression or name of custom polling query>",
    "sourceExpression": [
    "let ..."
    ]
}

Napiwek

Pamiętaj, aby zapoznać się z filmami wideo, blogami i nie tylko udostępnianymi przez społeczność ekspertów ds. analizy biznesowej w usłudze Power BI.

Wdrażanie tylko metadanych

Podczas publikowania nowej wersji pliku pbix z programu Power BI Desktop do obszaru roboczego, jeśli model o tej samej nazwie już istnieje, zostanie wyświetlony monit o zastąpienie istniejącego modelu.

Screenshot shows the Replace model dialog.

W niektórych przypadkach możesz nie chcieć zastąpić modelu, zwłaszcza przy użyciu odświeżania przyrostowego. Model w programie Power BI Desktop może być znacznie mniejszy niż model w usługa Power BI. Jeśli model w usługa Power BI ma zastosowane zasady odświeżania przyrostowego, może to mieć kilka lat danych historycznych, które zostaną utracone, jeśli model zostanie zastąpiony. Odświeżanie wszystkich danych historycznych może potrwać kilka godzin i spowodować przestój systemu dla użytkowników.

Zamiast tego lepiej jest wykonać wdrożenie tylko metadanych, co umożliwia wdrażanie nowych obiektów bez utraty danych historycznych. Jeśli na przykład dodano kilka miar, możesz wdrożyć tylko nowe miary bez konieczności odświeżania danych, co pozwala zaoszczędzić czas.

W przypadku obszarów roboczych przypisanych do pojemności Premium skonfigurowanej na potrzeby odczytu/zapisu punktu końcowego XMLA zgodne narzędzia umożliwiają wdrażanie tylko metadanych. Na przykład zestaw narzędzi ALM Toolkit jest narzędziem różnic schematu dla modeli usługi Power BI i może służyć do wdrażania tylko metadanych.

Pobierz i zainstaluj najnowszą wersję zestawu narzędzi ALM Toolkit z repozytorium Git usług Analysis Services. Szczegółowe wskazówki dotyczące korzystania z zestawu narzędzi ALM Toolkit nie są zawarte w dokumentacji firmy Microsoft. Linki do dokumentacji zestawu narzędzi ALM Toolkit i informacje na temat możliwości obsługi są dostępne na wstążce Pomoc . Aby przeprowadzić wdrożenie tylko metadanych, wykonaj porównanie i wybierz uruchomione wystąpienie programu Power BI Desktop jako źródło, a istniejący model w usługa Power BI jako element docelowy. Rozważ wyświetlone różnice i pomiń aktualizację tabeli z partycjami odświeżania przyrostowego lub użyj okna dialogowego Opcje , aby zachować partycje aktualizacji tabeli. Zweryfikuj wybór, aby zapewnić integralność modelu docelowego, a następnie zaktualizuj go.

Screenshot shows the ALM Toolkit window.

Programowe dodawanie zasad odświeżania przyrostowego i danych w czasie rzeczywistym

Możesz również użyć TMSL i TOM, aby dodać zasady odświeżania przyrostowego do istniejącego modelu za pośrednictwem punktu końcowego XMLA.

Uwaga

Aby uniknąć problemów ze zgodnością, upewnij się, że używasz najnowszej wersji bibliotek klienckich usług Analysis Services. Na przykład aby pracować z zasadami hybrydowymi, wersja musi mieć wartość 19.27.1.8 lub nowszą.

Proces obejmuje następujące kroki:

  1. Upewnij się, że model docelowy ma wymagany minimalny poziom zgodności. W programie SSMS kliknij prawym przyciskiem myszy pozycję [nazwa modelu]>Poziom zgodności właściwości.> Aby zwiększyć poziom zgodności, użyj skryptu createOrReplace TMSL lub sprawdź poniższy przykładowy kod TOM.

    a. Import policy - 1550
    b. Hybrid policy - 1565
    
  2. RangeStart Dodaj parametry i RangeEnd do wyrażeń modelu. W razie potrzeby dodaj również funkcję, aby przekonwertować wartości daty/godziny na klucze dat.

  3. Zdefiniuj RefreshPolicy obiekt z żądanym archiwizowaniem (kroczącym oknem) i okresami odświeżania przyrostowego, a także wyrażeniem źródłowym, które filtruje tabelę docelową na RangeStart podstawie parametrów i RangeEnd . Ustaw tryb zasad odświeżania na Import lub Hybrid w zależności od wymagań dotyczących danych w czasie rzeczywistym. Hybryda powoduje, że usługa Power BI dodaje partycję DirectQuery do tabeli, aby pobrać najnowsze zmiany ze źródła danych, które wystąpiły po ostatnim odświeżeniu.

  4. Dodaj zasady odświeżania do tabeli i wykonaj pełne odświeżanie, aby usługa Power BI partycjonuje tabelę zgodnie z wymaganiami.

W poniższym przykładzie kodu pokazano, jak wykonać poprzednie kroki przy użyciu funkcji TOM. Jeśli chcesz użyć tego przykładu w następujący sposób, musisz mieć kopię bazy danych AdventureWorksDW i zaimportować tabelę FactInternetSales do modelu. W przykładzie kodu przyjęto założenie, że RangeStart parametry i i RangeEndDateKey funkcja nie istnieją w modelu. Wystarczy zaimportować tabelę FactInternetSales i opublikować model w obszarze roboczym w usłudze Power BI Premium. Następnie zaktualizuj element workspaceUrl , aby przykładowy kod mógł nawiązać połączenie z modelem. Zaktualizuj więcej wierszy kodu w razie potrzeby.

using System;
using TOM = Microsoft.AnalysisServices.Tabular;
namespace Hybrid_Tables
{
    class Program
    {
        static string workspaceUrl = "<Enter your Workspace URL here>";
        static string databaseName = "AdventureWorks";
        static string tableName = "FactInternetSales";
        static void Main(string[] args)
        {
            using (var server = new TOM.Server())
            {
                // Connect to the dataset.
                server.Connect(workspaceUrl);
                TOM.Database database = server.Databases.FindByName(databaseName);
                if (database == null)
                {
                    throw new ApplicationException("Database cannot be found!");
                }
                if(database.CompatibilityLevel < 1565)
                {
                    database.CompatibilityLevel = 1565;
                    database.Update();
                }
                TOM.Model model = database.Model;
                // Add RangeStart, RangeEnd, and DateKey function.
                model.Expressions.Add(new TOM.NamedExpression {
                    Name = "RangeStart",
                    Kind = TOM.ExpressionKind.M,
                    Expression = "#datetime(2021, 12, 30, 0, 0, 0) meta [IsParameterQuery=true, Type=\"DateTime\", IsParameterQueryRequired=true]"
                });
                model.Expressions.Add(new TOM.NamedExpression
                {
                    Name = "RangeEnd",
                    Kind = TOM.ExpressionKind.M,
                    Expression = "#datetime(2021, 12, 31, 0, 0, 0) meta [IsParameterQuery=true, Type=\"DateTime\", IsParameterQueryRequired=true]"
                });
                model.Expressions.Add(new TOM.NamedExpression
                {
                    Name = "DateKey",
                    Kind = TOM.ExpressionKind.M,
                    Expression =
                        "let\n" +
                        "    Source = (x as datetime) => Date.Year(x)*10000 + Date.Month(x)*100 + Date.Day(x)\n" +
                        "in\n" +
                        "    Source"
                });
                // Apply a RefreshPolicy with Real-Time to the target table.
                TOM.Table salesTable = model.Tables[tableName];
                TOM.RefreshPolicy hybridPolicy = new TOM.BasicRefreshPolicy
                {
                    Mode = TOM.RefreshPolicyMode.Hybrid,
                    IncrementalPeriodsOffset = -1,
                    RollingWindowPeriods = 1,
                    RollingWindowGranularity = TOM.RefreshGranularityType.Year,
                    IncrementalPeriods = 1,
                    IncrementalGranularity = TOM.RefreshGranularityType.Day,
                    SourceExpression =
                        "let\n" +
                        "    Source = Sql.Database(\"demopm.database.windows.net\", \"AdventureWorksDW\"),\n" +
                        "    dbo_FactInternetSales = Source{[Schema=\"dbo\",Item=\"FactInternetSales\"]}[Data],\n" +
                        "    #\"Filtered Rows\" = Table.SelectRows(dbo_FactInternetSales, each [OrderDateKey] >= DateKey(RangeStart) and [OrderDateKey] < DateKey(RangeEnd))\n" +
                        "in\n" +
                        "    #\"Filtered Rows\""
                };
                salesTable.RefreshPolicy = hybridPolicy;
                model.RequestRefresh(TOM.RefreshType.Full);
                model.SaveChanges();
            }
            Console.WriteLine("{0}{1}", Environment.NewLine, "Press [Enter] to exit...");
            Console.ReadLine();
        }
    }
}