Delen via


TripPin deel 4 - Gegevensbronpaden

Deze meerdelige zelfstudie bevat informatie over het maken van een nieuwe gegevensbronextensie voor Power Query. De zelfstudie is bedoeld om opeenvolgend te worden uitgevoerd. Elke les bouwt voort op de connector die in de vorige lessen is gemaakt, en voegt incrementeel nieuwe mogelijkheden toe aan uw connector.

In deze les gaat u het volgende doen:

  • De verbindingslogica voor uw connector vereenvoudigen
  • De navigatietabelervaring verbeteren

Deze les vereenvoudigt de connector die in de vorige les is gebouwd door de vereiste functieparameters te verwijderen en de gebruikerservaring te verbeteren door over te stappen op een dynamisch gegenereerde navigatietabel.

Zie de sectie Gegevensbronpaden van de verwerking van verificatie voor uitgebreide uitleg over hoe referenties worden geïdentificeerd.

Gegevensbronpaden

Bij het aanroepen van een gegevensbronfunctie identificeert de M-engine welke referenties tijdens een evaluatie moeten worden gebruikt door een zoekopdracht uit te voeren op basis van de waarden voor het gegevensbrontype en het gegevensbronpad.

In de vorige les hebt u twee gegevensbronfuncties gedeeld, beide met één parameter 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);

De eerste keer dat u een query uitvoert die gebruikmaakt van een van de functies, ontvangt u een referentieprompt met vervolgkeuzelijsten waarmee u een pad en een verificatietype kunt selecteren.

Referenties met paden.

Als u dezelfde query opnieuw uitvoert, met dezelfde parameters, kan de M-engine de referenties in de cache vinden en wordt er geen referentieprompt weergegeven. Als u het url argument wijzigt in uw functie zodat het basispad niet meer overeenkomt, wordt er een nieuwe referentieprompt weergegeven voor het nieuwe pad.

U kunt alle referenties in de cache zien in de tabel Referenties in het venster M Query-uitvoer .

Tabblad Referenties.

Afhankelijk van het type wijziging leidt het wijzigen van de parameters van uw functie waarschijnlijk tot een referentiefout.

De connector vereenvoudigen

U vereenvoudigt nu uw connector door de parameters voor uw gegevensbronfunctie (TripPin.Contents) te verwijderen. U verwijdert ook de shared kwalificatie voor TripPin.Feeden laat deze staan als een interne functie.

Een van de ontwerpfilosieën van Power Query is om het dialoogvenster voor de eerste gegevensbron zo eenvoudig mogelijk te houden. Indien mogelijk moet u de gebruiker keuzes geven op navigatorniveau, in plaats van in het verbindingsdialoogvenster. Als een door de gebruiker opgegeven waarde programmatisch kan worden bepaald, kunt u overwegen deze toe te voegen als het hoogste niveau van de navigatietabel in plaats van een functieparameter.

Als u bijvoorbeeld verbinding maakt met een relationele database, hebt u mogelijk server-, database- en tabelnamen nodig. Zodra u weet met welke server verbinding moet worden gemaakt en referenties zijn opgegeven, kunt u de API van de database gebruiken om een lijst met databases op te halen en een lijst met tabellen in elke database. In dit geval moet alleen de servernaam een vereiste parameterDatabase zijn om het eerste verbindingsdialoogvenster zo eenvoudig mogelijk te houden. Table Dit zijn niveaus van de navigatietabel.

Omdat de TripPin-service een vast URL-eindpunt heeft, hoeft u de gebruiker niet om waarden te vragen. U verwijdert de URL-parameter uit uw functie en definieert een BaseUrl-variabele in uw connector.

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

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

U behoudt de functie, maar maakt deze TripPin.Feed niet meer gedeeld, koppelt deze niet meer aan een gegevensbrontype en vereenvoudigt de declaratie ervan. Vanaf dit punt gebruikt u deze alleen intern in dit sectiedocument.

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

Als u de TripPin.Contents() aanroep in uw TripPin.query.pq bestand bijwerkt en uitvoert in Visual Studio Code, ziet u een nieuwe referentieprompt. Houd er rekening mee dat er nu één waarde voor het gegevensbronpad is: TripPin.

Referenties zonder pad.

De navigatietabel verbeteren

In de eerste zelfstudie hebt u de ingebouwde functies gebruikt om verbinding te maken met de TripPin-service OData . Dit gaf u een mooi uitziende navigatietabel, gebaseerd op het TripPin-servicedocument, zonder code meer aan uw kant. De functie OData.Feed heeft automatisch het harde werk voor u gedaan. Omdat u het 'ruwer' maakt met behulp van Web.Contents in plaats van OData.Feed, moet u deze navigatietabel zelf opnieuw maken.

OData Navigator.

U gaat de volgende wijzigingen aanbrengen:

  1. Een lijst met items definiëren die moeten worden weergegeven in uw navigatietabel
  2. Weggaan met de entiteitsspecifieke functies (GetAirlineTables en GetAirportsTable)

Een navigatietabel genereren vanuit een lijst

U vermeldt de entiteiten die u wilt weergeven in de navigatietabel en bouwt de juiste URL om deze te openen. Omdat alle entiteiten zich onder hetzelfde hoofdpad bevinden, kunt u deze URL's dynamisch bouwen.

Ter vereenvoudiging van het voorbeeld maakt u alleen de drie entiteitssets beschikbaar (Airlines, Airports, Mensen), die worden weergegeven als Tabellen in M en slaat u de singleton (Me) over die als record zou worden weergegeven. U slaat het toevoegen van de functies over tot een latere les.

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

Vervolgens werkt u uw TripPinNavTable functie bij om de tabel een kolom tegelijk te bouwen. De kolom [Gegevens] voor elke entiteit wordt opgehaald door de volledige URL naar de entiteit aan te roepen TripPin.Feed .

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;

Wanneer u dynamisch URL-paden bouwt, moet u ervoor zorgen dat u duidelijk bent waar uw slashes (/) staan. Houd er rekening mee dat Uri.Combine de volgende regels gebruikt bij het combineren van paden:

  • Wanneer de relativeUri parameter begint met een /, wordt het volledige pad van de baseUri parameter vervangen
  • Als de relativeUri parameter niet begint met een / en baseUri eindigt op een /, wordt het pad toegevoegd
  • Als de relativeUri parameter niet begint met een / en baseUriniet eindigt op een /, wordt het laatste segment van het pad vervangen

In de volgende afbeelding ziet u voorbeelden hiervan:

Voorbeeld van Uri.Combine.

De entiteitsspecifieke functies verwijderen

Als u de connector gemakkelijker wilt onderhouden, verwijdert u de entiteitsspecifieke opmaakfuncties die u in de vorige les hebt gebruikt,GetAirlineTables en GetAirportsTable. In plaats daarvan werkt TripPin.Feed u bij om het JSON-antwoord te verwerken op een manier die werkt voor al uw entiteiten. U neemt met name het value veld van de geretourneerde OData JSON-nettolading en converteert het van een lijst met records naar een 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;

Notitie

Een nadeel van het gebruik van een algemene benadering voor het verwerken van uw entiteiten is dat u de mooie opmaak en typegegevens voor uw entiteiten kwijtraakt. Een latere sectie in deze zelfstudie laat zien hoe u schema afdwingt voor REST API-aanroepen.

Conclusie

In deze zelfstudie hebt u de connector opgeschoond en vereenvoudigd door de waarde van het gegevensbronpad te herstellen en over te stappen op een flexibelere indeling voor uw navigatietabel. Nadat u deze stappen hebt voltooid (of de voorbeeldcode in deze map gebruikt), retourneert de TripPin.Contents functie een navigatietabel in Power BI Desktop.

Navigator.

Volgende stappen

TripPin deel 5 - Paging