Číst v angličtině

Sdílet prostřednictvím


Zpracování schématu

V závislosti na zdroji dat mohou nebo nemusí být explicitně uvedeny informace o datových typech a názvech sloupců. Rozhraní REST API OData to obvykle zpracovávají pomocí definice $metadata a metoda Power Query OData.Feed automaticky zpracovává analýzu těchto informací a použije je na data vrácená ze zdroje OData.

Mnoho rozhraní REST API nemá způsob, jak programově určit jejich schéma. V těchto případech budete muset do konektoru zahrnout definici schématu.

Jednoduchý pevně zakódovaný přístup

Nejjednodušším přístupem je pevně zakódovat definici schématu do konektoru. To je dostatečné pro většinu případů použití.

Vynucování schématu u dat vrácených konektorem má celkově několik výhod, například:

  • Nastavení správných datových typů
  • Odebrání sloupců, které se koncovým uživatelům nemusí zobrazovat (například interní ID nebo informace o stavu).
  • Pokud chcete zajistit, aby každá stránka dat měla stejný tvar, přidejte všechny sloupce, které můžou v odpovědi chybět (rozhraní REST API obvykle označují, že pole by měla být null, když je úplně vynecháte).

Zobrazení existujícího schématu pomocí Table.Schema

Představte si následující kód, který vrátí jednoduchou tabulku z ukázkové služby TripPin OData:

let
    url = "https://services.odata.org/TripPinWebApiService/Airlines",
    source = Json.Document(Web.Contents(url))[value],
    asTable = Table.FromRecords(source)
in
    asTable

Poznámka

TripPin je zdroj OData, takže realisticky by bylo vhodnější jednoduše použít OData.Feed automatické zpracování schématu funkce. V tomto příkladu budete zacházet se zdrojem jako s typickým rozhraním REST API a používat Web.Contents k předvedení techniky ručního zakódování schématu.

Výsledkem této tabulky je:

Tabulka dat společnosti TripPin Airline.

Pomocí užitečné Table.Schema funkce můžete zkontrolovat datový typ sloupců:

let
    url = "https://services.odata.org/TripPinWebApiService/Airlines",
    source = Json.Document(Web.Contents(url))[value],
    asTable = Table.FromRecords(source)
in
    Table.Schema(asTable)

Výsledek Table.Schema použitý na data společnosti TripPin Airline.

AirlineCode i Name jsou typu any . Table.Schema vrátí mnoho metadat o sloupcích v tabulce, včetně názvů, pozic, informací o typu a mnoha pokročilých vlastností, jako je Přesnost, Měřítko a MaxLength. Prozatím byste se měli zabývat pouze přiřazeným typem (TypeName), primitivním typem (Kind) a to, jestli hodnota sloupce může být null (IsNullable).

Definování jednoduché tabulky schématu

Tabulka schématu se bude skládat ze dvou sloupců:

Column Detaily
Název Název sloupce. Musí se shodovat s názvem ve výsledcích vrácených službou.
Typ Datový typ M, který nastavíte. Může to být primitivní typ (text, číslo, datum a tak dále) nebo přiřazený typ (Int64.Type, Currency.Type atd.).

Pevně zakódovaná tabulka schématu Airlines pro tabulku nastaví její AirlineCode sloupce Name text a bude vypadat takto:

Airlines = #table({"Name", "Type"}, {
        {"AirlineCode", type text},
        {"Name", type text}
    })

Při pohledu na některé z dalších koncových bodů zvažte následující tabulky schématu:

Tabulka Airports obsahuje čtyři pole, která chcete zachovat (včetně jednoho typu record):

Airports = #table({"Name", "Type"}, {
        {"IcaoCode", type text},
        {"Name", type text},
        {"IataCode", type text},
        {"Location", type record}
    })

Tabulka People obsahuje sedm polí, včetně lists (Emails, AddressInfo), sloupce s možnou hodnotou null (Gender) a sloupce s přiřazeným typem (Concurrency):

People = #table({"Name", "Type"}, {
        {"UserName", type text},
        {"FirstName", type text},
        {"LastName", type text},
        {"Emails", type list},
        {"AddressInfo", type list},
        {"Gender", type nullable text},
        {"Concurrency", Int64.Type}
    })

Všechny tyto tabulky můžete umístit do jedné hlavní tabulky SchemaTableschématu:

SchemaTable = #table({"Entity", "SchemaTable"}, {
        {"Airlines", Airlines},
        {"Airports", Airports},
        {"People", People}
    })

Tabulka schémat

Pomocná funkce SchemaTransformTable

Pomocná SchemaTransformTable funkce popsaná níže se použije k vynucení schémat ve vašich datech. Přebírá následující parametry:

Parametr Typ Popis
table table Tabulka dat, pro která chcete vynutit schéma
schema table Tabulka schématu pro čtení informací o sloupcích z, s následujícím typem: type table [Name = text, Type = type].
enforceSchema Číslo (volitelné) Výčet, který řídí chování funkce.
Výchozí hodnota (EnforceSchema.Strict = 1) zajišťuje, aby výstupní tabulka odpovídala tabulce schématu, kterou poskytla, přidáním chybějících sloupců a odebráním dalších sloupců.
Možnost EnforceSchema.IgnoreExtraColumns = 2 lze použít k zachování dalších sloupců ve výsledku.
Při EnforceSchema.IgnoreMissingColumns = 3 použití se budou ignorovat chybějící sloupce i nadbytečné sloupce.

Logika pro tuto funkci vypadá přibližně takto:

  1. Zjistěte, jestli ve zdrojové tabulce chybí nějaké sloupce.
  2. Určete, jestli existují nějaké další sloupce.
  3. Ignorovat strukturované sloupce (typu list, recorda table) a sloupce nastavené na typ any.
  4. Slouží Table.TransformColumnTypes k nastavení jednotlivých typů sloupců.
  5. Změnit pořadí sloupců podle pořadí, ve kterém se zobrazují v tabulce schématu
  6. Nastavte typ v samotné tabulce pomocí Value.ReplaceType.

Poznámka

Posledním krokem k nastavení typu tabulky bude potřeba, aby uživatelské rozhraní Power Query odvozování informací o typech při prohlížení výsledků v editoru dotazů, což někdy může vést k dvojitému volání rozhraní API.

Spojení všech součástí dohromady

V širším kontextu kompletního rozšíření se zpracování schématu provede při vrácení tabulky z rozhraní API. Tato funkce se obvykle provádí na nejnižší úrovni stránkovací funkce (pokud existuje) s informacemi o entitách předávaných z navigační tabulky.

Vzhledem k tomu, že velká část implementace stránkovacích a navigačních tabulek je specifická pro kontext, úplný příklad implementace pevně zakódovaného mechanismu zpracování schématu se zde nezobrazí. Tento příklad TripPin ukazuje, jak by mohlo vypadat komplexní řešení.

Sofistikovaný přístup

Pevně zakódovaná implementace, kterou jsme probírali výše, je dobrou úlohou zajistit, aby schémata zůstala konzistentní pro jednoduché repsonses JSON, ale je omezená na parsování první úrovně odpovědi. Hluboce vnořené datové sady by mohly těžit z následujícího přístupu, který využívá M Types.

Tady je rychlá aktualizace typů v jazyce M ze specifikace jazyka:

Hodnota typu je hodnota, která klasifikuje jiné hodnoty. Hodnota klasifikovaná typem je označena tak, aby odpovídala danému typu. Systém typů M se skládá z následujících typů typů:

  • Primitivní typy, které klasifikují primitivní hodnoty (, , , datetimedurationdatetimezone, list, logical, , nullnumber, record, timetext, type) a zahrnují také řadu abstraktních typů (function, table, anya ).nonedatebinary
  • Typy záznamů, které klasifikují hodnoty záznamů na základě názvů polí a typů hodnot.
  • Typy seznamů, které klasifikují seznamy pomocí jednoho základního typu položky.
  • Typy funkcí, které klasifikují hodnoty funkcí na základě typů jejich parametrů a návratových hodnot.
  • Typy tabulek, které klasifikují hodnoty tabulky na základě názvů sloupců, typů sloupců a klíčů.
  • Typy s možnou hodnotou null, které kromě všech hodnot klasifikovaných základním typem klasifikují hodnotu null.
  • Typy typů, které klasifikují hodnoty, které jsou typy.

Pomocí nezpracovaného výstupu JSON, který získáte (nebo vyhledáním definic v $metadata služby), můžete definovat následující typy záznamů, které představují komplexní typy OData:

LocationType = type [
    Address = text,
    City = CityType,
    Loc = LocType
];

CityType = type [
    CountryRegion = text,
    Name = text,
    Region = text
];

LocType = type [
    #"type" = text,
    coordinates = {number},
    crs = CrsType
];

CrsType = type [
    #"type" = text,
    properties = record
];

Všimněte si, jak LocationType odkazuje na CityType strukturované sloupce a LocType znázorní je.

U entit nejvyšší úrovně, které chcete reprezentovat jako Tabulky, můžete definovat typy tabulek:

AirlinesType = type table [
    AirlineCode = text,
    Name = text
];
AirportsType = type table [
    Name = text,
    IataCode = text,
    Location = LocationType
];
PeopleType = type table [
    UserName = text,
    FirstName = text,
    LastName = text,
    Emails = {text},
    AddressInfo = {nullable LocationType},
    Gender = nullable text,
    Concurrency  Int64.Type
];

Potom můžete aktualizovat proměnnou SchemaTable (kterou můžete použít jako vyhledávací tabulku pro mapování entit-typ) tak, aby používala tyto nové definice typu:

SchemaTable = #table({"Entity", "Type"}, {
    {"Airlines", AirlinesType},
    {"Airports", AirportsType},
    {"People", PeopleType}
});

Při vynucování schématu dat můžete spoléhat na společnou funkci (Table.ChangeType) podobně jako SchemaTransformTable v předchozím cvičení. Na rozdíl od SchemaTransformTabletypu Table.ChangeType skutečné tabulky M jako argumentu použije schéma rekurzivně pro všechny vnořené typy. Jeho podpis je:

Table.ChangeType = (table, tableType as type) as nullable table => ...

Poznámka

Pro flexibilitu je možné tuto funkci použít u tabulek a také seznamy záznamů (což je způsob, jakým jsou tabulky reprezentovány v dokumentu JSON).

Pak budete muset aktualizovat kód konektoru, aby se změnil schema parametr z table a na a type, a přidat volání .Table.ChangeType Podrobnosti o tom, jak to udělat, jsou velmi specifické pro implementaci, a proto by se zde neměly podrobně zabývat. Tento příklad rozšířeného konektoru TripPin ukazuje ucelené řešení, které implementuje tento sofistikovanější přístup ke zpracování schématu.