TripPin parte 4 - Percorsi origine dati
Questa esercitazione in più parti illustra la creazione di una nuova estensione dell'origine dati per Power Query. L'esercitazione è destinata a essere eseguita in sequenza: ogni lezione si basa sul connettore creato nelle lezioni precedenti, aggiungendo in modo incrementale nuove funzionalità al connettore.
In questa lezione verranno illustrate le procedure seguenti:
- Semplificare la logica di connessione per il connettore
- Migliorare l'esperienza della tabella di spostamento
Questa lezione semplifica il connettore compilato nella lezione precedente rimuovendo i parametri di funzione necessari e migliorando l'esperienza utente passando a una tabella di spostamento generata dinamicamente.
Per una spiegazione approfondita del modo in cui vengono identificate le credenziali, vedere la sezione Percorsi origine dati di Gestione dell'autenticazione.
Percorsi origine dati
Quando si richiama una funzione di origine dati, il motore M identifica le credenziali da usare durante una valutazione eseguendo una ricerca in base ai valori Tipo origine dati e Percorso origine dati.
Nella lezione precedente sono state condivise due funzioni di origine dati, entrambe con un singolo parametro 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);
La prima volta che si esegue una query che usa una delle funzioni, si riceverà un prompt delle credenziali con elenchi a discesa che consente di selezionare un percorso e un tipo di autenticazione.
Se si esegue di nuovo la stessa query, con gli stessi parametri, il motore M è in grado di individuare le credenziali memorizzate nella cache e non viene visualizzata alcuna richiesta di credenziali. Se si modifica l'argomento url
nella funzione in modo che il percorso di base non corrisponda più, viene visualizzata una nuova richiesta di credenziali per il nuovo percorso.
È possibile visualizzare tutte le credenziali memorizzate nella cache nella tabella Credenziali nella finestra Output query M.
A seconda del tipo di modifica, la modifica dei parametri della funzione genererà probabilmente un errore di credenziale.
Semplificazione del connettore
A questo punto si semplifica il connettore rimuovendo i parametri per la funzione dell'origine dati (TripPin.Contents
). Si rimuoverà anche il shared
qualificatore per TripPin.Feed
e lo si lascerà come funzione solo interna.
Una delle filosofie di progettazione di Power Query consiste nel mantenere il più semplice possibile la finestra di dialogo iniziale dell'origine dati. Se possibile, è consigliabile fornire all'utente scelte a livello di Strumento di navigazione, anziché nella finestra di dialogo di connessione. Se un valore fornito dall'utente può essere determinato a livello di codice, è consigliabile aggiungerlo come primo livello della tabella di spostamento anziché come parametro di funzione.
Ad esempio, quando ci si connette a un database relazionale, potrebbero essere necessari nomi di server, database e tabelle.
Dopo aver appreso il server a cui connettersi e sono state specificate le credenziali, è possibile usare l'API del database per recuperare un elenco di database e un elenco di tabelle contenute in ogni database.
In questo caso, per mantenere la finestra di dialogo di connessione iniziale il più semplice possibile, solo il nome del server deve essere un parametroDatabase
obbligatorio e Table
sarebbe il livello della tabella di spostamento.
Poiché il servizio TripPin ha un endpoint URL fisso, non è necessario richiedere all'utente alcun valore. Si rimuoverà il parametro URL dalla funzione e si definirà una variabile BaseUrl nel connettore.
BaseUrl = "https://services.odata.org/v4/TripPinService/";
[DataSource.Kind="TripPin", Publish="TripPin.Publish"]
shared TripPin.Contents = () => TripPinNavTable(BaseUrl) as table;
Si manterrà la TripPin.Feed
funzione, ma non la si renderà più condivisa, non più associata a un tipo di origine dati e si semplifica la dichiarazione. Da questo punto in poi, verrà usato solo internamente all'interno di questo documento di sezione.
TripPin.Feed = (url as text) =>
let
source = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
json = Json.Document(source)
in
json;
Se si aggiorna la TripPin.Contents()
chiamata nel TripPin.query.pq
file ed eseguirla in Visual Studio Code, verrà visualizzata una nuova richiesta di credenziali. Si noti che ora è presente un singolo valore di Percorso origine dati: TripPin.
Miglioramento della tabella di spostamento
Nella prima esercitazione sono state usate le funzioni predefinite OData
per connettersi al servizio TripPin.
Questo ti ha dato una bella tabella di spostamento, basata sul documento del servizio TripPin, senza più codice sul tuo lato.
La funzione OData.Feed ha eseguito automaticamente il lavoro duro.
Poiché si usa Web.Contents anziché OData.Feed, è necessario ricreare manualmente questa tabella di spostamento.
Verranno apportate le modifiche seguenti:
- Definire un elenco di elementi da visualizzare nella tabella di spostamento
- Non usare le funzioni specifiche dell'entità (
GetAirlineTables
eGetAirportsTable
)
Generazione di una tabella di spostamento da un elenco
Verranno elencate le entità che si desidera esporre nella tabella di spostamento e si creerà l'URL appropriato per accedervi. Poiché tutte le entità si trovano nello stesso percorso radice, sarà possibile compilare questi URL in modo dinamico.
Per semplificare l'esempio, si esporranno solo i tre set di entità (Airlines, Airports, People), che verrebbero esposti come Tabelle in M e ignorare il singleton (Me) che verrebbe esposto come record. Si ignorerà l'aggiunta delle funzioni fino a una lezione successiva.
RootEntities = {
"Airlines",
"Airports",
"People"
};
Si aggiorna quindi la TripPinNavTable
funzione per compilare la tabella una colonna alla volta.
La colonna [Data] per ogni entità viene recuperata chiamando TripPin.Feed
con l'URL completo dell'entità.
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;
Quando si creano dinamicamente percorsi URL, assicurarsi di essere chiari dove si trovano le barre (/). Si noti che Uri.Combine usa le regole seguenti quando si combinano i percorsi:
- Quando il
relativeUri
parametro inizia con /, sostituirà l'intero percorso delbaseUri
parametro - Se il
relativeUri
parametro non inizia con a / ebaseUri
termina con un /, il percorso viene aggiunto - Se il
relativeUri
parametro non inizia con un /ebaseUri
non termina con un /, l'ultimo segmento del percorso viene sostituito
L'immagine seguente mostra alcuni esempi:
Rimuovere le funzioni specifiche dell'entità
Per semplificare la manutenzione del connettore, rimuovere le funzioni di formattazione specifiche dell'entità usate nella lezione precedente eGetAirlineTables
GetAirportsTable
.
Si aggiornerà TripPin.Feed
invece per elaborare la risposta JSON in modo che funzioni per tutte le entità.
In particolare, si accetta il value
campo del payload JSON OData restituito e lo si converte da un elenco di record a una tabella.
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;
Nota
Uno svantaggio dell'uso di un approccio generico per elaborare le entità è che si perdono le informazioni di formattazione e tipo per le entità. Una sezione successiva di questa esercitazione illustra come applicare lo schema alle chiamate API REST.
Conclusione
In questa esercitazione è stato pulito e semplificato il connettore correggendo il valore percorso origine dati e passando a un formato più flessibile per la tabella di spostamento. Dopo aver completato questi passaggi (o usando il codice di esempio in questa directory), la TripPin.Contents
funzione restituisce una tabella di spostamento in Power BI Desktop.