Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este tutorial de varias partes se describe la creación de una nueva extensión de origen de datos para Power Query. El tutorial está diseñado para realizarse secuencialmente: cada lección se basa en el conector creado en las lecciones anteriores, agregando incrementalmente nuevas funcionalidades al conector.
En esta lección:
- Simplifique la lógica de conexión de su conector
- Mejora de la experiencia de la tabla de navegación
Esta lección simplifica el conector integrado en la lección anterior quitando sus parámetros de función necesarios y mejorando la experiencia del usuario pasando a una tabla de navegación generada dinámicamente.
Para obtener una explicación detallada de cómo se identifican las credenciales, vaya a la sección Rutas del origen de datos de Gestión de la autenticación.
Rutas de acceso del origen de datos
Cuando se invoca una función de origen de datos, el motor de M identifica las credenciales que se usarán durante una evaluación mediante una búsqueda basada en los valores tipo de origen de datos y ruta de acceso del origen de datos .
En la lección anterior ha compartido dos funciones de origen de datos, ambas con un único parámetro 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 primera vez que ejecute una consulta utilizando una de las funciones, recibirá un aviso de credenciales con menús desplegables. Este mensaje le permite seleccionar una ruta de acceso y un tipo de autenticación.
Si vuelve a ejecutar la misma consulta, con los mismos parámetros, el motor de M puede localizar las credenciales almacenadas en caché y no se muestra ningún mensaje de credenciales. Si modifica el url argumento a la función para que la ruta de acceso base ya no coincida, se muestra una nueva solicitud de credenciales para la nueva ruta de acceso.
Las credenciales almacenadas en caché se muestran en la tabla Credenciales de la ventana Salida de consulta M .
Dependiendo del tipo de cambio, la modificación de los parámetros de tu función probablemente llevará a un error de credenciales.
Simplificación del conector
Ahora, simplifique el conector quitando los parámetros de la función de origen de datos (TripPin.Contents). También debe quitar el shared calificador para TripPin.Feed, y dejarlo como una función interna solamente.
Una de las filosofías de diseño de Power Query es mantener el cuadro de diálogo inicial del origen de datos lo más sencillo posible. Si es posible, debe proporcionar al usuario opciones en el nivel navegador, en lugar de en el cuadro de diálogo de conexión. Si un valor proporcionado por el usuario se puede determinar mediante programación, considere la posibilidad de agregarlo como el nivel superior de la tabla de navegación en lugar de un parámetro de función.
Por ejemplo, al conectarse a una base de datos relacional, es posible que necesite nombres de servidor, base de datos y tabla. Una vez que conozca el servidor al que conectarse y se proporcionen credenciales, puede usar la API de la base de datos para capturar una lista de bases de datos y una lista de tablas contenidas en cada base de datos. En este caso, para mantener el cuadro de diálogo de conexión inicial lo más sencillo posible, solo el nombre del servidor debe ser un parámetro obligatorio yDatabaseTable sería niveles de la tabla de navegación.
Dado que el servicio TripPin tiene un punto de conexión de dirección URL fijo, no es necesario solicitar al usuario ningún valor. Debe quitar el parámetro url de la función y definir una variable BaseUrl en el conector.
BaseUrl = "https://services.odata.org/v4/TripPinService/";
[DataSource.Kind="TripPin", Publish="TripPin.Publish"]
shared TripPin.Contents = () => TripPinNavTable(BaseUrl) as table;
Mantiene la TripPin.Feed función, pero ya no la convierte en compartida, ya no la asocia con un tipo de origen de datos y simplifica su declaración. A partir de este punto, solo se usa internamente en este documento de sección.
TripPin.Feed = (url as text) =>
let
source = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
json = Json.Document(source)
in
json;
Si actualiza el TripPin.Contents() de llamada en el archivo TripPin.query.pq y lo ejecuta en Visual Studio Code, hay una nueva solicitud de credenciales. Además, ahora hay un valor único para la ruta de acceso del origen de datos: TripPin.
Mejora de la tabla de navegación
En el primer tutorial, ha usado las funciones integradas OData para conectarse al servicio TripPin. Estas funciones le proporcionaron una tabla de navegación atractiva, basada en el documento de servicio TripPin, sin necesidad de más código por su parte. La función OData.Feed realizó automáticamente el trabajo duro para usted. Dado que está "improvisando" utilizando Web.Contents en lugar de OData.Feed, debe recrear esta tabla de navegación por su cuenta.
Realizará los siguientes cambios:
- Definir una lista de elementos que se van a mostrar en la tabla de navegación
- Desasoje las funciones específicas de la entidad (
GetAirlineTablesyGetAirportsTable)
Generación de una tabla de navegación a partir de una lista
Debe enumerar las entidades que desea exponer en la tabla de navegación y crear la dirección URL adecuada para acceder a ellas. Puesto que todas las entidades están en la misma ruta de acceso raíz, puede compilar estas direcciones URL dinámicamente.
Para simplificar el ejemplo, solo expone los tres conjuntos de entidades (Líneas aéreas, aeropuertos, personas), que se exponerían como tablas en M y omiten el singleton (Me) que se expondría como un registro. Puede omitir la adición de las funciones hasta una lección posterior.
RootEntities = {
"Airlines",
"Airports",
"People"
};
A continuación, actualice la función TripPinNavTable para crear la tabla una columna a la vez. La columna [Datos] de cada entidad se recupera mediante la llamada a TripPin.Feed con la URL completa de la entidad.
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;
Al construir dinámicamente rutas de URL, asegúrese de tener claro dónde están las barras diagonales (/) . Uri.Combine usa las siguientes reglas al combinar rutas de acceso:
- Cuando el
relativeUriparámetro comienza por /, reemplaza toda la ruta de acceso delbaseUriparámetro. - Si el
relativeUriparámetro no comienza con un / ybaseUritermina con un /, se anexa la ruta. - Si el
relativeUriparámetro no comienza por / ybaseUrino termina con /, se reemplaza el último segmento de la ruta de acceso.
En la imagen siguiente se muestran ejemplos de estas reglas:
Eliminación de las funciones específicas de la entidad
Para que el conector sea más fácil de mantener, debe quitar las funciones de formato específicas de la entidad que usó en la lección anterior: GetAirlineTables y GetAirportsTable. En su lugar, se actualiza TripPin.Feed para procesar la respuesta JSON de una manera que funcione para todas las entidades. En concreto, toma el value campo de la carga JSON de OData devuelta y la convierte de una lista de registros a una tabla.
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:
Una desventaja de usar un enfoque genérico para procesar las entidades es que se pierde la información de formato y tipo adecuados para las entidades. En una sección posterior de este tutorial se muestra cómo aplicar el esquema en las llamadas a la API REST.
Conclusión
En este tutorial, limpiaste y simplificaste tu conector corrigiendo el valor de la ruta de acceso de tu origen de datos y cambiando a un formato más flexible para tu tabla de navegación. Después de completar estos pasos (o usar el código de ejemplo de este directorio), la TripPin.Contents función devuelve una tabla de navegación en Power BI Desktop.