Udostępnij przez


TripPin — część 4 — ścieżki źródła danych

Ten wieloczęściowy samouczek obejmuje tworzenie nowego rozszerzenia źródła danych dla dodatku Power Query. Samouczek ma być wykonywany sekwencyjnie — każda lekcja opiera się na łączniku utworzonym w poprzednich lekcjach, przyrostowo dodając nowe możliwości do łącznika.

W tej lekcji wykonasz następujące czynności:

  • Uproszczenie logiki połączenia dla łącznika
  • Ulepszanie doświadczenia tabeli nawigacyjnej

Ta lekcja upraszcza łącznik wbudowany w poprzedniej lekcji , usuwając jego wymagane parametry funkcji i poprawiając środowisko użytkownika, przechodząc do dynamicznie generowanej tabeli nawigacji.

Aby uzyskać szczegółowe wyjaśnienie sposobu identyfikowania poświadczeń, przejdź do sekcji Ścieżki źródła danych w Obsłudze uwierzytelniania.

Ścieżki źródła danych

Podczas wywoływania funkcji źródła danych aparat języka M identyfikuje poświadczenia do użycia podczas oceny, wykonując wyszukiwanie na podstawie wartości Rodzaj źródła danych i Ścieżka źródła danych .

W poprzedniej lekcji udostępniono dwie funkcje źródła danych, obie z pojedynczym parametrem Uri.Type .

[DataSource.Kind="TripPin"]
shared TripPin.Feed = Value.ReplaceType(TripPinImpl, type function (url as Uri.Type) as any);

[DataSource.Kind="TripPin", Publish="TripPin.Publish"]
shared TripPin.Contents =  Value.ReplaceType(TripPinNavTable, type function (url as Uri.Type) as any);

Przy pierwszym uruchomieniu zapytania, które używa jednej z funkcji, zostanie wyświetlony monit o podanie poświadczeń z listami rozwijanymi. Ten monit umożliwia wybranie ścieżki i typu uwierzytelniania.

Zrzut ekranu pokazujący zakładkę Błędy wyniku zapytania M z komunikatem o poświadczeniach.

Jeśli ponownie uruchomisz to samo zapytanie, z tymi samymi parametrami aparat języka M będzie mógł zlokalizować buforowane poświadczenia i nie zostanie wyświetlony żaden monit o podanie poświadczeń. Jeśli zmodyfikujesz url argument funkcji tak, aby ścieżka podstawowa nie odpowiadała, zostanie wyświetlony nowy monit o podanie nowej ścieżki poświadczeń.

Wszystkie buforowane poświadczenia są wyświetlane w tabeli Credentials w oknie Dane wyjściowe zapytania języka M.

Zrzut ekranu przedstawiający dane wyjściowe zapytania języka M z buforowanymi poświadczeniami na karcie Poświadczenia.

W zależności od typu zmiany modyfikowanie parametrów funkcji prawdopodobnie spowoduje wystąpienie błędu poświadczeń.

Upraszczanie łącznika

Teraz uprość łącznik, usuwając parametry funkcji źródła danych (TripPin.Contents). Należy również usunąć kwalifikator shared dla TripPin.Feed i pozostawić jako funkcję wewnętrzną.

Jedną z filozofii projektowych dodatku Power Query jest zapewnienie możliwie prostego okna dialogowego początkowego źródła danych. Jeśli to możliwe, należy podać użytkownikowi opcje na poziomie Nawigator, a nie w oknie dialogowym połączenia. Jeśli wartość podana przez użytkownika można określić programowo, rozważ dodanie jej jako najwyższego poziomu tabeli nawigacji, a nie parametru funkcji.

Na przykład podczas nawiązywania połączenia z relacyjną bazą danych może być konieczne utworzenie nazw serwerów, baz danych i tabel. Gdy znasz serwer do nawiązania połączenia i podano poświadczenia, możesz użyć interfejsu API bazy danych, aby pobrać listę baz danych oraz listę tabel zawartych w każdej bazie danych. W takim przypadku, aby okno dialogowe połączenia początkowego było tak proste, jak to możliwe, tylko nazwa serwera powinna być wymaganym parametrem —Database i Table będzie to poziomy tabeli nawigacji.

Ponieważ usługa TripPin ma stały endpoint URL, nie musisz pytać użytkownika o żadne wartości. Musisz usunąć parametr adresu URL z funkcji i zdefiniować zmienną BaseUrl w łączniku.

BaseUrl = "https://services.odata.org/v4/TripPinService/";

[DataSource.Kind="TripPin", Publish="TripPin.Publish"]
shared TripPin.Contents = () => TripPinNavTable(BaseUrl) as table;

Zachowujesz funkcję TripPin.Feed, ale nie jest już ona udostępniana, nie jest już powiązana z rodzajem źródła danych, a jej deklaracja jest uproszczona. Od tego momentu używasz go tylko wewnętrznie w tej części dokumentu.

TripPin.Feed = (url as text) =>
    let
        source = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
        json = Json.Document(source)
    in
        json;

Jeśli zaktualizujesz wywołanie TripPin.Contents() w pliku TripPin.query.pq i uruchomisz je w Visual Studio Code, pojawi się nowy monit dotyczący poświadczeń. Ponadto istnieje teraz jedna wartość ścieżki źródła danych — TripPin.

Zrzut ekranu przedstawiający kartę Błędy w wynikach zapytania języka M z komunikatem o poświadczeniach odnoszącym się tylko do ścieżki TripPin.

Ulepszanie tabeli nawigacji

W pierwszym samouczku użyto wbudowanych funkcji OData do połączenia z usługą TripPin. Te funkcje dały ci ładnie wyglądającą tabelę nawigacji opartą na dokumencie usługi TripPin, bez żadnego kodu po twojej stronie. Funkcja OData.Feed automatycznie wykonała ci ciężką pracę. Ponieważ "używasz prowizorycznie" Web.Contents zamiast OData.Feed, musisz samodzielnie odtworzyć tę tabelę nawigacji.

Zrzut ekranu przedstawiający nawigatora Power Query wyświetlanego podczas korzystania z wbudowanych funkcji OData.

Wprowadzisz następujące zmiany:

  1. Definiowanie listy elementów do pokazania w tabeli nawigacji
  2. Odejście od funkcji specyficznych dla jednostki (GetAirlineTables i GetAirportsTable)

Generowanie tabeli nawigacji z listy

Musisz wyświetlić listę jednostek, które chcesz uwidocznić w tabeli nawigacji, i utworzyć odpowiedni adres URL, aby uzyskać do nich dostęp. Ponieważ wszystkie jednostki znajdują się w tej samej ścieżce głównej, można dynamicznie tworzyć te adresy URL.

Aby uprościć ten przykład, uwidaczniasz tylko trzy zestawy jednostek (Linie lotnicze, Lotniska, Osoby), które będą widoczne jako tabele w języku M, i pomiń singleton (Me), który będzie uwidoczniony jako Rekord. Dodawanie funkcji można pominąć do późniejszej lekcji.

RootEntities = {
    "Airlines",
    "Airports",
    "People"
};

Następnie zaktualizujesz funkcję TripPinNavTable, aby budować tabelę kolumna po kolumnie. Kolumna [Data] dla każdej jednostki jest pobierana przez wywołanie TripPin.Feed pełnego adresu URL jednostki.

TripPinNavTable = (url as text) as table =>
    let
        entitiesAsTable = Table.FromList(RootEntities, Splitter.SplitByNothing()),
        rename = Table.RenameColumns(entitiesAsTable, {{"Column1", "Name"}}),
        // Add Data as a calculated column
        withData = Table.AddColumn(rename, "Data", each TripPin.Feed(Uri.Combine(url, [Name])), Uri.Type),
        // Add ItemKind and ItemName as fixed text values
        withItemKind = Table.AddColumn(withData, "ItemKind", each "Table", type text),
        withItemName = Table.AddColumn(withItemKind, "ItemName", each "Table", type text),
        // Indicate that the node should not be expandable
        withIsLeaf = Table.AddColumn(withItemName, "IsLeaf", each true, type logical),
        // Generate the nav table
        navTable = Table.ToNavigationTable(withIsLeaf, {"Name"}, "Name", "Data", "ItemKind", "ItemName", "IsLeaf")
    in
        navTable;

Podczas dynamicznego tworzenia ścieżek adresów URL upewnij się, że dokładnie wiesz, gdzie znajdują się ukośniki pionowe (/). Uri.Combine używa następujących reguł podczas łączenia ścieżek:

  • relativeUri Gdy parametr zaczyna się od /, zastępuje całą ścieżkę parametru baseUri
  • relativeUri Jeśli parametr nie zaczyna się od / i baseUri kończy się /, ścieżka zostaje dołączona
  • relativeUri Jeśli parametr nie zaczyna się od / i baseUrinie kończy się na /, ostatni segment ścieżki zostanie zastąpiony

Na poniższej ilustracji przedstawiono przykłady tych reguł:

Zrzut ekranu przedstawiający ścieżki URL i pokazujący reguły użycia ukośników (slashów) przy łączeniu ścieżek.

Usuwanie funkcji specyficznych dla jednostki

Aby ułatwić konserwację łącznika, należy usunąć funkcje formatowania specyficzne dla jednostki użyte w poprzedniej lekcji —GetAirlineTables i GetAirportsTable. Zamiast tego zaktualizujesz TripPin.Feed, aby przetwarzać odpowiedź w formacie JSON w sposób, który działa dla wszystkich jednostek. W szczególności należy wziąć pole value ze zwróconego obciążenia OData JSON i przekonwertować je z listy rekordów na tabelę.

TripPin.Feed = (url as text) =>
    let
        source = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
        json = Json.Document(source),
        // The response is a JSON record - the data we want is a list of records in the "value" field
        value = json[value],
        asTable = Table.FromList(value, Splitter.SplitByNothing()),
        // expand all columns from the record
        fields = Record.FieldNames(Table.FirstValue(asTable, [Empty = null])),
        expandAll = Table.ExpandRecordColumn(asTable, "Column1", fields)
    in
        expandAll;

Uwaga / Notatka

Wadą stosowania ogólnego podejścia do przetwarzania elementów jest utrata dokładnych informacji o formatowaniu i typie elementów. W dalszej części tego samouczka pokazano, jak wymusić schemat wywołań interfejsu API REST.

Podsumowanie

W tym samouczku oczyściłeś i uprościłeś swój łącznik, poprawiając wartość ścieżki źródła danych i przechodząc na bardziej elastyczny format dla tabeli nawigacyjnej. Po wykonaniu tych kroków (lub użyciu przykładowego kodu w tym katalogu) TripPin.Contents funkcja zwraca tabelę nawigacji w programie Power BI Desktop.

Zrzut ekranu przedstawiający tabelę nawigacji zwróconą przez funkcję TripPin.Contents.

Dalsze kroki

TripPin — część 5 — stronicowanie