Поделиться через


Часть 4 TripPin — пути к источнику данных

В этом руководстве рассматривается создание нового расширения источника данных для Power Query. Это руководство предназначено для последовательного выполнения каждого урока— каждый урок, созданный на основе соединителя, созданного на предыдущих уроках, постепенно добавляя новые возможности в соединитель.

В этом уроке вы научитесь:

  • Упрощение логики подключения для соединителя
  • Улучшение интерфейса таблицы навигации

Этот урок упрощает соединитель, созданный на предыдущем занятии , путем удаления необходимых параметров функции и улучшения пользовательского интерфейса путем перемещения в динамически созданную таблицу навигации.

Подробное описание определения учетных данных см. в разделе "Пути источника данных" в разделе"Обработка проверки подлинности".

Пути к источнику данных

При вызове функции источника данных подсистема M определяет учетные данные, используемые во время оценки, выполняя поиск на основе значений типа источника данных и пути к источнику данных.

На предыдущем занятии вы поделились двумя функциями источника данных, как с одним параметром 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);

При первом запуске запроса, использующего одну из функций, вы получите запрос учетных данных с раскрывающимися списками, которые позволяют выбрать путь и тип проверки подлинности.

Учетные данные с путями.

При повторном выполнении того же запроса с теми же параметрами подсистема M может найти кэшированные учетные данные, а запрос учетных данных не отображается. При изменении аргумента url в функцию таким образом, чтобы базовый путь больше не совпадал, для нового пути отображается новая строка учетных данных.

В окне вывода запроса M можно просмотреть любые кэшированные учетные данные в таблице "Учетные данные".

Вкладка

В зависимости от типа изменения, изменение параметров функции, скорее всего, приведет к ошибке учетных данных.

Упрощение соединителя

Теперь вы упростите соединитель, удалив параметры для функции источника данных (TripPin.Contents). Вы также удалите shared квалификатор для TripPin.Feed, а затем оставьте его внутренней функцией.

Одной из философий проектирования Power Query является максимально простое диалоговое окно исходного источника данных. Если это возможно, вы должны предоставить пользователю выбор на уровне навигатора, а не в диалоговом окне подключения. Если предоставленное пользователем значение можно определить программным способом, попробуйте добавить его как верхний уровень таблицы навигации, а не параметр функции.

Например, при подключении к реляционной базе данных может потребоваться имя сервера, базы данных и таблицы. После того как вы знаете сервер для подключения и учетные данные, можно использовать API базы данных для получения списка баз данных и списка таблиц, содержащихся в каждой базе данных. В этом случае, чтобы сохранить диалоговое окно начального подключения как можно проще, только имя сервера должно быть обязательным параметром иDatabaseTable будет уровнями таблицы навигации.

Так как служба TripPin имеет фиксированную конечную точку URL-адреса, пользователю не нужно запрашивать какие-либо значения. Вы удалите параметр URL-адреса из функции и определите переменную BaseUrl в соединителе.

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

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

Вы сохраните функцию, но больше не делаете TripPin.Feed ее общим, больше не связываете ее с типом источника данных и упрощает его объявление. С этого момента вы будете использовать его только внутри этого документа раздела.

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

Если вы обновите TripPin.Contents() вызов в файле и запустите его в TripPin.query.pq Visual Studio Code, появится новая строка учетных данных. Обратите внимание, что теперь существует одно значение пути источника данных — TripPin.

Учетные данные без пути.

Улучшение таблицы навигации

В первом руководстве вы использовали встроенные OData функции для подключения к службе TripPin. Это дало вам хорошую таблицу навигации, основанную на документе службы TripPin, без дополнительного кода на стороне. Функция OData.Feed автоматически выполняла сложную работу. Так как вы "грубо" используете web.Contents , а не OData.Feed, вам потребуется повторно создать эту таблицу навигации самостоятельно.

OData Navigator.

Вы собираетесь внести следующие изменения:

  1. Определение списка элементов для отображения в таблице навигации
  2. Не удаляйтесь с определенными функциями сущности (GetAirlineTables и GetAirportsTable)

Создание таблицы навигации из списка

Вы перечислите сущности, которые вы хотите предоставить в таблице навигации, и создадите соответствующий URL-адрес для доступа к ним. Так как все сущности находятся под одинаковым корневым путем, вы сможете динамически создавать эти URL-адреса.

Чтобы упростить пример, вы будете предоставлять только три набора сущностей (Airlines, Аэропорты, Люди), которые будут предоставляться в виде таблиц в M, и пропустить одноэлементный (Me), который будет предоставляться как запись. Вы пропустите добавление функций до последующего урока.

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

Затем вы обновляете TripPinNavTable функцию, чтобы создать таблицу в столбец за раз. Столбец [Data] для каждой сущности извлекается путем вызова TripPin.Feed полного URL-адреса сущности.

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;

При динамическом создании путей URL-адресов убедитесь, что вы ясно, где находятся косые черты (/). Обратите внимание, что Uri.Combine использует следующие правила при сочетании путей:

  • relativeUri Когда параметр начинается с /, он заменит весь путь baseUri параметра.
  • relativeUri Если параметр не начинается с /и baseUri заканчивается /, путь добавляется
  • relativeUri Если параметр не начинается с / и baseUriне заканчивается с /, последний сегмент пути заменяется

На следующем рисунке показаны примеры этого:

Пример Uri.Combine.

Удаление определенных функций сущности

Чтобы упростить обслуживание соединителя, удалите функции форматирования сущности, используемые на предыдущем занятии,GetAirlineTables и GetAirportsTable. Вместо этого вы обновите TripPin.Feed ответ JSON таким образом, который будет работать для всех сущностей. В частности, вы принимаете value поле возвращаемой полезных данных OData JSON и преобразуете его из списка записей в таблицу.

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;

Примечание.

Недостаток использования универсального подхода к обработке сущностей заключается в том, что вы теряете хорошую информацию о форматировании и типе для сущностей. В следующем разделе этого руководства показано, как применить схему к вызовам REST API.

Заключение

В этом руководстве вы очистили и упростили соединитель, исправив значение пути источника данных и перейдя к более гибкому формату для таблицы навигации. Выполнив эти действия (или используя пример кода в этом каталоге), TripPin.Contents функция возвращает таблицу навигации в Power BI Desktop.

Навигатор.

Следующие шаги

Часть 5 TripPin — разбиение по страницам