Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
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:
- Tworzenie funkcji podstawowej, która wywołuje interfejs API REST przy użyciu biblioteki Web.Contents
- Dowiedz się, jak ustawiać nagłówki żądań i przetwarzać odpowiedź w formacie JSON
- Używanie programu Power BI Desktop do rozmieszczania odpowiedzi w formacie przyjaznym dla użytkownika
Ta lekcja konwertuje łącznik OData dla usługi TripPin (utworzony w poprzedniej lekcji) na łącznik podobny do utworzonego dla dowolnego interfejsu API RESTful. OData to RESTful API, ale z ustalonym zestawem konwencji. Zaletą usługi OData jest zapewnienie schematu, protokołu pobierania danych i standardowego języka zapytań. Usunięcie możliwości korzystania z usługi OData.Feed wymaga samodzielnego wprowadzenia tych funkcji do łącznika.
Podsumowanie łącznika OData
Przed usunięciem funkcji OData z łącznika wykonajmy szybką recenzję tego, co obecnie robi (głównie za kulisami), aby pobrać dane z usługi.
Otwórz projekt rozszerzenia TripPin z części 1 w programie Visual Studio Code. Otwórz plik Query i wklej następujące zapytanie:
TripPin.Feed("https://services.odata.org/v4/TripPinService/Me")
Otwórz program Fiddler, a następnie oceń bieżący plik Power Query w programie Visual Studio Code.
W programie Fiddler istnieją trzy żądania do serwera:
-
/Me: rzeczywisty adres URL, którego żądasz. -
/$metadata: FunkcjaOData.Feedautomatycznie inicjuje wywołanie w celu określenia schematu i informacji o typie odpowiedzi. -
/Me/BestFriend: Jedno z pól, które było (chętnie) ściągane po wyświetleniu /Me singleton. W takim przypadku wywołanie spowodowało status204 No Content.
Ocena M jest głównie leniwa. W większości przypadków wartości danych są pobierane/ściągane tylko wtedy, gdy są potrzebne. Istnieją scenariusze (takie jak /Me/BestFriend), w których wartość jest ciągnięta z niecierpliwością. To zachowanie zwykle występuje, gdy informacje o typie są potrzebne dla członka, a silnik nie ma innego sposobu na określenie typu niż pobranie wartości i sprawdzenie jej. Tworzenie rzeczy leniwych (czyli unikanie chętnych ściągnięcia) jest jednym z kluczowych aspektów tworzenia łącznika M wydajne.
Sprawdź nagłówki żądań wysłanych wraz z zapytaniami oraz format JSON odpowiedzi żądania /Me.
{
"@odata.context": "https://services.odata.org/v4/TripPinService/$metadata#Me",
"UserName": "aprilcline",
"FirstName": "April",
"LastName": "Cline",
"MiddleName": null,
"Gender": "Female",
"Age": null,
"Emails": [ "April@example.com", "April@contoso.com" ],
"FavoriteFeature": "Feature1",
"Features": [ ],
"AddressInfo": [
{
"Address": "P.O. Box 555",
"City": {
"Name": "Lander",
"CountryRegion": "United States",
"Region": "WY"
}
}
],
"HomeAddress": null
}
Po zakończeniu przetwarzania zapytania okno wyników PQTest powinno wyświetlić wartość rekord dla elementu singleton Me.
Jeśli porównasz pola w oknie danych wyjściowych z polami zwróconymi w nieprzetworzonej odpowiedzi JSON, zauważysz niezgodność. Wynik zapytania zawiera inne pola (Friends, Trips, GetFriendsTrips), które nie są wyświetlane nigdzie w odpowiedzi JSON. Funkcja OData.Feed automatycznie dołącza te pola do rekordu na podstawie schematu zwróconego przez $metadata. Ta różnica jest dobrym przykładem tego, jak łącznik może rozszerzać i/lub ponownie formatować odpowiedzi z usługi, aby zapewnić lepsze doświadczenie użytkownika.
Tworzenie podstawowego łącznika REST
Teraz dodaj nową wyeksportowaną funkcję do łącznika, która wywołuje funkcję Web.Contents.
Aby pomyślnie wysyłać żądania internetowe do usługi OData, należy jednak ustawić niektóre standardowe nagłówki OData. W tym celu należy zdefiniować wspólny zestaw nagłówków jako nową zmienną w łączniku:
DefaultRequestHeaders = [
#"Accept" = "application/json;odata.metadata=minimal", // column name and values only
#"OData-MaxVersion" = "4.0" // we only support v4
];
Zmieniać swoją implementację funkcji TripPin.Feed, aby zamiast używania OData.Feed, korzystać z funkcji Web.Contents do wykonania żądania internetowego oraz analizować wynik jako dokument JSON.
TripPinImpl = (url as text) =>
let
source = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
json = Json.Document(source)
in
json;
Pamiętaj, aby zbudować łącznik po wprowadzeniu zmian w pliku łącznika. Następnie możesz ocenić plik zapytania (TripPin.query.pq). Wynik rekordu /Me teraz przypomina nieprzetworzone dane JSON, które znajdowały się w żądaniu programu Fiddler.
Jeśli oglądasz program Fiddler podczas działania nowej funkcji, zauważysz również, że proces teraz wykonuje jedno żądanie sieciowe, a nie trzy. Gratulacje — osiągnięto 300% wzrost wydajności! Utraciliśmy wszystkie informacje o typie i schemacie, ale nie trzeba jeszcze skupiać się na tej części.
Zaktualizuj zapytanie, aby uzyskać dostęp do niektórych jednostek/tabel TripPin, takich jak:
https://services.odata.org/v4/TripPinService/Airlineshttps://services.odata.org/v4/TripPinService/Airportshttps://services.odata.org/v4/TripPinService/Me/Trips
Zauważysz, że ścieżki, które były używane do zwracania ładnie sformatowanych tabel, zwracają teraz pole "value" najwyższego poziomu z osadzonym polem [List]. Aby wynik był użyteczny w scenariuszach konsumpcji przez użytkowników końcowych, należy dokonać pewnych przekształceń.
Tworzenie przekształceń w Power Query
Chociaż możliwe jest ręczne tworzenie przekształceń języka M, większość osób woli używać dodatku Power Query do kształtowania danych. Możesz otworzyć rozszerzenie w programie Power BI Desktop i używać go do projektowania zapytań w celu przekształcenia danych wyjściowych w bardziej przyjazny dla użytkownika format. Ponownie skompiluj rozwiązanie, skopiuj nowy plik rozszerzenia do katalogu Łączniki danych niestandardowych i uruchom ponownie program Power BI Desktop.
Uruchom nowe puste zapytanie i wklej następujący wiersz na pasku formuły:
= TripPin.Feed("https://services.odata.org/v4/TripPinService/Airlines")
Pamiętaj, aby uwzględnić znak = .
Manipuluj danymi wyjściowymi, dopóki nie będzie wyglądało to jak oryginalne źródło danych OData — tabela z dwiema kolumnami: AirlineCode i Name.
Wynikowe zapytanie powinno wyglądać mniej więcej tak:
let
Source = TripPin.Feed("https://services.odata.org/v4/TripPinService/Airlines"),
value = Source[value],
toTable = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
expand = Table.ExpandRecordColumn(toTable, "Column1", {"AirlineCode", "Name"}, {"AirlineCode", "Name"})
in
expand
Nadaj kwerendzie nazwę ("Airlines").
Utwórz nowe puste zapytanie. Tym razem użyj TripPin.Feed funkcji , aby uzyskać dostęp do jednostki /Airports. Zastosuj przekształcenia, dopóki nie uzyskasz czegoś podobnego do poniższej tabeli. Pasujące zapytanie jest zgodne z tabelą — nadaj tej kwerendzie nazwę ("Lotniska").
let
Source = TripPin.Feed("https://services.odata.org/v4/TripPinService/Airports"),
value = Source[value],
#"Converted to Table" = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"Name", "IcaoCode", "IataCode", "Location"}, {"Name", "IcaoCode", "IataCode", "Location"}),
#"Expanded Location" = Table.ExpandRecordColumn(#"Expanded Column1", "Location", {"Address", "Loc", "City"}, {"Address", "Loc", "City"}),
#"Expanded City" = Table.ExpandRecordColumn(#"Expanded Location", "City", {"Name", "CountryRegion", "Region"}, {"Name.1", "CountryRegion", "Region"}),
#"Renamed Columns" = Table.RenameColumns(#"Expanded City",{{"Name.1", "City"}}),
#"Expanded Loc" = Table.ExpandRecordColumn(#"Renamed Columns", "Loc", {"coordinates"}, {"coordinates"}),
#"Added Custom" = Table.AddColumn(#"Expanded Loc", "Latitude", each [coordinates]{1}),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Longitude", each [coordinates]{0}),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom1",{"coordinates"}),
#"Changed Type" = Table.TransformColumnTypes(#"Removed Columns",{{"Name", type text}, {"IcaoCode", type text}, {"IataCode", type text}, {"Address", type text}, {"City", type text}, {"CountryRegion", type text}, {"Region", type text}, {"Latitude", type number}, {"Longitude", type number}})
in
#"Changed Type"
Ten proces można powtórzyć, aby uzyskać więcej ścieżek w ramach usługi. Gdy jesteś gotowy/gotowa, przejdź do następnego kroku tworzenia tymczasowej tabeli nawigacyjnej.
Symulowanie tabeli nawigacji
Teraz utworzysz tabelę (przy użyciu kodu M), która przedstawia ładnie sformatowane jednostki TripPin.
Uruchom nowe puste zapytanie i wyświetl zaawansowany edytor.
Wklej następujące zapytanie:
let
source = #table({"Name", "Data"}, {
{ "Airlines", Airlines },
{ "Airports", Airports }
})
in
source
Jeśli nie ustawiłeś swojego ustawienia Poziomy prywatności na wartość "Zawsze ignoruj ustawienia poziomu prywatności" (znane również jako "Szybkie łączenie"), zostanie wyświetlony komunikat o prywatności.
Monity dotyczące prywatności są wyświetlane, gdy łączysz dane z wielu źródeł i nie określono poziomu prywatności dla co najmniej jednego źródła. Wybierz przycisk Kontynuuj i ustaw poziom prywatności najwyższego źródła na Publiczny.
Wybierz pozycję Zapisz , a tabela pojawi się. Chociaż ta tabela nie jest jeszcze tabelą nawigacji, zapewnia podstawową funkcjonalność, którą należy przekształcić w jedną w kolejnej lekcji.
Sprawdzanie kombinacji danych nie występuje podczas uzyskiwania dostępu do wielu źródeł danych z poziomu rozszerzenia. Ponieważ wszystkie wywołania źródła danych wykonywane z poziomu rozszerzenia dziedziczą ten sam kontekst autoryzacji, założeniem jest to, że są one "bezpieczne", aby połączyć. Rozszerzenie jest zawsze traktowane jako pojedyncze źródło danych, jeśli chodzi o reguły kombinacji danych. Użytkownicy nadal będą otrzymywać zwykłe powiadomienia o prywatności podczas łączenia twojego źródła z innymi źródłami M.
Jeśli uruchomisz program Fiddler i wybierz przycisk Odśwież podgląd w edytorze Power Query, zanotuj oddzielne żądania internetowe dla każdego elementu w tabeli nawigacji. Te oddzielne żądania wskazują, że występuje przedwczesna ocena, co nie jest idealne podczas tworzenia tabel nawigacyjnych zawierających wiele elementów. Kolejne lekcje pokazują, jak utworzyć właściwą tabelę nawigacji, która obsługuje leniwą ewaluację.
Podsumowanie
W tej lekcji pokazano, jak utworzyć prosty łącznik dla usługi REST. W takim przypadku istniejące rozszerzenie OData stało się standardowym rozszerzeniem REST (przy użyciu biblioteki Web.Contents), ale te same pojęcia mają zastosowanie, jeśli tworzysz nowe rozszerzenie od podstaw.
W następnej lekcji wykonasz zapytania utworzone w tej lekcji przy użyciu programu Power BI Desktop i przekształcisz je w prawdziwą tabelę nawigacji w rozszerzeniu.