Del via


TripPin del 4 – Datakildestier

Dette selvstudium i flere dele dækker oprettelsen af en ny datakildeudvidelse til Power Query. Selvstudiet er beregnet til at blive udført sekventielt – hver lektion bygger på den connector, der blev oprettet i tidligere lektioner, og føjer trinvist nye funktioner til din connector.

I denne lektion skal du:

  • Gør forbindelseslogikken for din connector enklere
  • Gør navigationstabeloplevelsen bedre

Denne lektion forenkler den connector, der blev bygget i den forrige lektion , ved at fjerne de påkrævede funktionsparametre og forbedre brugeroplevelsen ved at flytte til en dynamisk genereret navigationstabel.

Du kan finde en detaljeret forklaring af, hvordan legitimationsoplysninger identificeres, i afsnittet Datakildestier under Håndtering af godkendelse.

Datakildestier

Når du aktiverer en datakildefunktion, identificerer M-programmet, hvilke legitimationsoplysninger der skal bruges under en evaluering, ved at udføre et opslag baseret på værdierne For datakildetype og Datakildesti .

I den forrige lektion delte du to datakildefunktioner, begge med en enkelt URI.Type-parameter .

[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);

Første gang du kører en forespørgsel, der bruger en af funktionerne, modtager du en prompt om legitimationsoplysninger med rullemenuer, hvor du kan vælge en sti og en godkendelsestype.

Legitimationsoplysninger med stier.

Hvis du kører den samme forespørgsel igen med de samme parametre, kan M-programmet finde de cachelagrede legitimationsoplysninger, og der vises ingen prompt om legitimationsoplysninger. Hvis du ændrer argumentet url til din funktion, så basisstien ikke længere stemmer overens, vises der en ny prompt om legitimationsoplysninger for den nye sti.

Du kan se alle cachelagrede legitimationsoplysninger i tabellen Legitimationsoplysninger i vinduet M-forespørgselsoutput .

Fanen Legitimationsoplysninger.

Afhængigt af ændringstypen vil ændring af parametrene for din funktion sandsynligvis resultere i en fejl i legitimationsoplysningerne.

Forenkling af connectoren

Du forenkler nu din connector ved at fjerne parametrene for din datakildefunktion (TripPin.Contents). Du skal også fjerne kvalifikatoren shared for TripPin.Feedog lade den være en funktion, der kun er intern.

En af designfilosofierne i Power Query er at holde den indledende dialogboks for datakilden så enkel som muligt. Hvis det overhovedet er muligt, skal du give brugeren valgmuligheder på navigatorniveau i stedet for i forbindelsesdialogboksen. Hvis en bruger angivet værdi kan bestemmes programmatisk, kan du overveje at tilføje den som det øverste niveau i navigationstabellen i stedet for en funktionsparameter.

Når du f.eks. opretter forbindelse til en relationsdatabase, skal du muligvis bruge server-, database- og tabelnavne. Når du ved, at serveren skal oprette forbindelse til, og der er angivet legitimationsoplysninger, kan du bruge databasens API til at hente en liste over databaser og en liste over tabeller i hver database. I dette tilfælde er det kun servernavnet, der skal være en påkrævet parameter for at holde den indledende forbindelsesdialogboks så enkel som muligt –Database og Table det vil være niveauer i navigationstabellen.

Da TripPin-tjenesten har et fast URL-slutpunkt, behøver du ikke at spørge brugeren om nogen værdier. Du skal fjerne URL-parameteren fra din funktion og definere en BaseUrl-variabel i din connector.

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

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

Du beholder funktionen TripPin.Feed , men gør den ikke længere delt, knytter den ikke længere til en datakildetype og forenkler erklæringen. Fra nu af skal du kun bruge den internt i dette sektionsdokument.

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

Hvis du opdaterer opkaldet TripPin.Contents() i din TripPin.query.pq fil og kører det i Visual Studio Code, får du vist en ny prompt om legitimationsoplysninger. Bemærk, at der nu er en enkelt værdi for datakildestien – TripPin.

Legitimationsoplysninger uden sti.

Forbedring af navigationstabellen

I det første selvstudium brugte du de indbyggede OData funktioner til at oprette forbindelse til TripPin-tjenesten. Dette gav dig en flot navigationstabel, der er baseret på TripPin-tjenestedokumentet, uden mere kode på din side. Funktionen OData.Feed udførte automatisk det hårde arbejde for dig. Da du bruger Web.Contents i stedet for OData.Feed, skal du selv oprette denne navigationstabel igen.

OData Navigator.

Du skal foretage følgende ændringer:

  1. Definer en liste over elementer, der skal vises i navigationstabellen
  2. Undlad at bruge de objektspecifikke funktioner (GetAirlineTables og GetAirportsTable)

Oprettelse af en navigationstabel ud fra en liste

Du skal angive de objekter, du vil vise, i navigationstabellen og oprette den relevante URL-adresse for at få adgang til dem. Da alle objekterne er under den samme rodsti, kan du oprette disse URL-adresser dynamisk.

For at forenkle eksemplet viser du kun de tre enhedssæt (Airlines, Airports, People), som vises som tabeller i M, og springer singletonen (Me), der vises som en post, over. Du springer tilføjelsen af funktionerne over indtil en senere lektion.

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

Du opdaterer derefter din TripPinNavTable funktion for at oprette tabellen en kolonne ad gangen. Kolonnen [Data] for hvert objekt hentes ved at kalde TripPin.Feed med den fulde URL-adresse til objektet.

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;

Når du opretter URL-stier dynamisk, skal du sørge for, at du er klar over, hvor dine skråstreger (/) er! Bemærk, at Uri.Combine bruger følgende regler, når stier kombineres:

  • Når parameteren relativeUri starter med en /, erstatter den hele stien til baseUri parameteren
  • Hvis parameteren relativeUri ikke starter med en / og baseUri slutter med en /, tilføjes stien
  • Hvis parameteren relativeUri ikke starter med en / og baseUri ikke slutter med en /, erstattes det sidste segment af stien

På følgende billede vises eksempler på dette:

Uri.Combine-eksempel.

Fjern de objektspecifikke funktioner

Hvis du vil gøre det nemmere at vedligeholde din connector, skal du fjerne de objektspecifikke formateringsfunktioner, du brugte i den forrige lektion –GetAirlineTables og GetAirportsTable. I stedet skal du opdatere TripPin.Feed for at behandle JSON-svaret på en måde, der fungerer for alle dine enheder. Du tager specifikt feltet value for den returnerede OData JSON-nyttedata og konverterer den fra en liste over poster til en 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;

Bemærk

En ulempe ved at bruge en generisk tilgang til at behandle dine enheder er, at du mister de pæne formaterings- og typeoplysninger for dine enheder. I et senere afsnit i dette selvstudium kan du se, hvordan du gennemtvinger skema på REST API-kald.

Konklusion

I dette selvstudium har du ryddet op i og forenklet din connector ved at rette værdien af datakildestien og flytte til et mere fleksibelt format til navigationstabellen. Når du har fuldført disse trin (eller brugt eksempelkoden i denne mappe), TripPin.Contents returnerer funktionen en navigationstabel i Power BI Desktop.

Navigator.

Næste trin

TripPin Del 5 – sideinddeling