Manipulando transformações

Para situações em que a resposta da fonte de dados não é apresentada em um formato que Power BI pode consumir diretamente, Power Query pode ser usado para executar uma série de transformações.

Transformações estáticas

Na maioria dos casos, os dados são apresentados de maneira consistente pela fonte de dados: nomes de coluna, tipos de dados e estrutura hierárquica são consistentes para um determinado ponto de extremidade. Nessa situação, é apropriado sempre aplicar o mesmo conjunto de transformações para obter os dados em um formato aceitável para Power BI.

Um exemplo de transformação estática pode ser encontrado no tutorial TripPin Part 2 – Data Connector para um Serviço REST quando a fonte de dados é tratada como um serviço REST padrão:

let
    Source = TripPin.Feed("https://services.odata.org/v4/TripPinService/Airlines"),
    value = Source[value],
    toTable = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    expand = Table.ExpandRecordColumn(toTable, "Column1", {"AirlineCode", "Name"}, {"AirlineCode", "Name"})
in
    expand

As transformações neste exemplo são:

  1. Source é um Registro retornado de uma chamada para TripPin.Feed(...) .
  2. Você recebe o valor de um dos Source pares chave-valor. O nome da chave é value e você armazena o resultado em uma variável chamada value .
  3. value é uma lista, que você converte em uma tabela. Cada elemento em value se torna uma linha na tabela, que você pode chamar toTable .
  4. Cada elemento em value é um Registro. toTable tem todos eles em uma única coluna: "Column1" . Esta etapa esmaeia todos os dados com chave em uma coluna chamada e todos os dados com chave em uma coluna chamada "AirlineCode" , para cada linha em "AirlineCode" "Name" "Name" toTable . "Column1" é substituído por essas duas novas colunas.

No final do dia, você é deixado com os dados em um formato tabular simples que Power BI pode consumir e renderizar facilmente:

Dados em formato tabular.

É importante observar que uma sequência de transformações estáticas dessa especificidade só é aplicável a um único ponto de extremidade. No exemplo acima, essa sequência de transformações só funcionará se e existirem na resposta do ponto de extremidade REST, pois elas são em código no "AirlineCode" "Name" código M. Portanto, essa sequência de transformações poderá não funcionar se você tentar atingir o /Event ponto de extremidade.

Esse alto nível de especificidade pode ser necessário para efetuar o pushing de dados para uma tabela de navegação, mas para funções de acesso a dados mais gerais, é recomendável que você execute apenas transformações apropriadas para todos os pontos de extremidade.

Observação

Certifique-se de testar transformações em uma variedade de circunstâncias de dados. Se o usuário não tiver dados no ponto de extremidade, suas transformações resultarão em uma tabela /airlines vazia com o esquema correto? Ou é encontrado um erro durante a avaliação? Consulte TripPin Part 7: Advanced Schema with M Types (TripPin Parte 7: Advanced Schema with M Types) para uma discussão sobre teste de unidade.

Transformações dinâmicas

Às vezes, uma lógica mais complexa é necessária para converter respostas de API em formulários estáveis e consistentes apropriados para Power BI de dados.

Respostas de API inconsistentes

Fluxo de controle básico M (se instruções, códigos de status HTTP, tente... Blocos catch e assim por diante) normalmente são suficientes para lidar com situações em que há algumas maneiras pelas quais a API responde.

Determinando o esquema em tempo real

Algumas APIs são projetadas de forma que várias informações devem ser combinadas para obter o formato tabular correto. Considere a resposta do ponto de extremidade do Smartsheet /sheets [], que contém uma matriz de nomes de coluna e uma matriz de linhas de dados. O Conector do Smartsheet é capaz de analisar essa resposta da seguinte maneira:

raw = Web.Contents(...),
columns = raw[columns],
columnTitles = List.Transform(columns, each [title]),
columnTitlesWithRowNumber = List.InsertRange(columnTitles, 0, {"RowNumber"}),
                
RowAsList = (row) =>
    let
        listOfCells = row[cells],
        cellValuesList = List.Transform(listOfCells, each if Record.HasFields(_, "value") then [value]
                else null),
        rowNumberFirst = List.InsertRange(cellValuesList, 0, {row[rowNumber]})
    in
        rowNumberFirst,

listOfRows = List.Transform(raw[rows], each RowAsList(_)),
result = Table.FromRows(listOfRows, columnTitlesWithRowNumber)
  1. Primeiro, lidar com informações de título de coluna. Você pode efetuar pull do registro de cada coluna em uma Lista, prependendo de uma coluna que você sabe que sempre será title representada como esta primeira RowNumber coluna.
  2. Em seguida, você pode definir uma função que permite analisar uma linha em uma Lista de value células s. Você pode, novamente, rowNumber pré-anexar informações.
  3. Aplique sua RowAsList() função a cada um dos s row retornados na resposta da API.
  4. Converta a Lista em uma tabela, especificando os headers de coluna.