Olvasás angol nyelven

Megosztás a következőn keresztül:


Séma kezelése

Az adatforrástól függően előfordulhat, hogy az adattípusokra és az oszlopnevekre vonatkozó információk kifejezetten megadhatók vagy nem. Az OData REST API-k általában a $metadata definícióval kezelik ezt, a Power Query OData.Feed metódus pedig automatikusan kezeli ezeket az információkat, és alkalmazza azokat az OData-forrásból visszaadott adatokra.

Sok REST API nem tudja programozott módon meghatározni a sémáját. Ezekben az esetekben sémadefiníciót kell tartalmaznia az összekötőben.

Egyszerű, szigorúan kódolt megközelítés

A legegyszerűbb módszer a sémadefiníciók az összekötőbe való kódolása. Ez a legtöbb használati esetben elegendő.

Általánosságban elmondható, hogy az összekötő által visszaadott adatok sémájának kényszerítése több előnnyel is jár, például:

  • A megfelelő adattípusok beállítása.
  • Eltávolítja azokat az oszlopokat, amelyeket nem kell megjeleníteni a végfelhasználók számára (például belső azonosítókat vagy állapotinformációkat).
  • A válaszból esetleg hiányzó oszlopok hozzáadásával biztosíthatja, hogy minden adatoldal azonos alakú legyen (a REST API-k általában azt jelzik, hogy a mezőknek null értékűnek kell lenniük, ha teljesen kihagyják őket).

A meglévő séma megtekintése a következővel: Table.Schema

Vegye figyelembe az alábbi kódot, amely egy egyszerű táblát ad vissza a TripPin OData mintaszolgáltatásból:

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

Megjegyzés

A TripPin egy OData-forrás, ezért reálisabban érdemes a függvény automatikus sémakezelését használni OData.Feed . Ebben a példában a forrást egy tipikus REST API-ként fogja kezelni, és Web.Contents a sémák kézzel történő keménykódolásának technikáját mutatja be.

Ez a táblázat az eredmény:

A TripPin Légitársaság adatainak táblázata.

A hasznos Table.Schema függvénnyel ellenőrizheti az oszlopok adattípusát:

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

A TripPin Légitársaság adataira alkalmazott Table.Schema eredménye.

Az AirlineCode és a Name típus is any . Table.Schema Sok metaadatot ad vissza a tábla oszlopairól, beleértve a neveket, a pozíciókat, a típusadatokat és számos speciális tulajdonságot, például a pontosságot, a méretezést és a MaxLengthet. Egyelőre csak az írott típus (), a primitív típus (TypeNameKind) és az oszlop értéke lehet null (IsNullable).

Egyszerű sématábla definiálása

A sématábla két oszlopból áll:

Oszlop Részletek
Név Az oszlop neve. Ennek meg kell egyeznie a szolgáltatás által visszaadott eredményekben szereplő névvel.
Típus A beállítani kívánt M adattípus. Ez lehet egy primitív típus (szöveg, szám, dátum/idő stb.), vagy egy írott típus (Int64.Type, Currency.Type stb.).

A tábla rögzített sématáblája a Airlines következőképpen állítja be és Name állítja be az AirlineCode oszlopokattext:

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

A többi végpontot tekintve vegye figyelembe a következő sématáblákat:

A Airports tábla négy megtartandó mezővel rendelkezik (beleértve a típus recordegyikét):

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

A People táblázat hét mezővel rendelkezik, beleértve listaz s (Emails, AddressInfo), a null értékű oszlopot (Gender), és egy írott típusú (Concurrency) oszlopot:

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}
    })

Ezeket a táblákat egyetlen fő sématáblába SchemaTablehelyezheti:

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

Sématáblázat.

A SchemaTransformTable segédfüggvény

Az SchemaTransformTable alábbiakban ismertetett segédfüggvény a sémák kikényszerítésére szolgál az adatokon. A következő paramétereket veszi igénybe:

Paraméter Típus Leírás
table table Azon adattábla, amelyen a sémát érvényesíteni szeretné.
schema table Az oszlopinformációkat beolvasni kívánt sématábla a következő típussal: type table [Name = text, Type = type].
enforceSchema szám (nem kötelező) A függvény viselkedését vezérlő szám.
Az alapértelmezett érték (EnforceSchema.Strict = 1) biztosítja, hogy a kimeneti tábla megegyezik a hiányzó oszlopok hozzáadásával és a további oszlopok eltávolításával megadott sématáblával.
Ezzel EnforceSchema.IgnoreExtraColumns = 2 a beállítással megőrizheti a további oszlopokat az eredményben.
A használat során EnforceSchema.IgnoreMissingColumns = 3 a rendszer figyelmen kívül hagyja a hiányzó oszlopokat és a további oszlopokat is.

A függvény logikája a következőképpen néz ki:

  1. Állapítsa meg, hogy vannak-e hiányzó oszlopok a forrástáblából.
  2. Állapítsa meg, hogy vannak-e további oszlopok.
  3. Figyelmen kívül hagyja a strukturált oszlopokat (típuslistrecord, és ) és tablea típusra anybeállított oszlopokat.
  4. Az egyes oszloptípusok beállítására használható Table.TransformColumnTypes .
  5. Az oszlopok átrendezése a sématáblában megjelenő sorrend alapján.
  6. Állítsa be magát a típust a táblán a következővel Value.ReplaceType: .

Megjegyzés

A táblatípus beállításának utolsó lépése megszünteti, hogy a Power Query felhasználói felülete típusadatokat vonjon le a lekérdezésszerkesztőben az eredmények megtekintésekor, ami néha dupla hívást eredményezhet az API-hoz.

Végső összeállítás

A teljes bővítmény nagyobb kontextusában a sémakezelés akkor történik meg, amikor a rendszer visszaad egy táblát az API-ból. Ez a funkció általában a lapozófüggvény legalsó szintjén (ha létezik) történik, és egy navigációs táblából továbbított entitásadatokkal.

Mivel a lapozási és navigációs táblák implementálásának nagy része környezetfüggő, itt nem jelenik meg a szigorúan kódolt sémakezelő mechanizmus implementálásának teljes példája. Ez a TripPin-példa bemutatja, hogyan nézhet ki egy végpontok közötti megoldás.

Kifinomult megközelítés

A fent tárgyalt kemény kóddal ellátott implementáció jó feladat annak biztosításához, hogy a sémák konzisztensek maradjanak az egyszerű JSON-repsonok esetében, de ez a válasz első szintjének elemzésére korlátozódik. A mélyen beágyazott adathalmazok az alábbi megközelítés előnyeit élvezik, amely kihasználja az M-típusok előnyeit.

Íme egy gyors frissítés az M nyelv típusairól a Nyelvi specifikációból:

A típusérték olyan érték, amely más értékeket sorol be . A típus szerint besorolt értéknek az adott típusnak kell megfelelnie . Az M típusú rendszer a következő típusokból áll:

  • Primitív típusok, amelyek primitív értékeket osztályoznak (binary, date, , datetimezonedurationdatetime, listlogicalnumberrecordnull, , text, ), time), typeés számos absztrakt típust is tartalmaznak (function, table, , anyés ).none
  • Rekordtípusok, amelyek mezőnevek és értéktípusok alapján osztályozzák a rekordértékeket.
  • Listatípusok, amelyek egyetlen elem alaptípusával osztályozzák a listákat.
  • Függvénytípusok, amelyek a paraméterek típusai alapján osztályozzák a függvényértékeket, és visszaadják az értékeket.
  • Táblázattípusok, amelyek oszlopnevek, oszloptípusok és kulcsok alapján sorolják be a táblaértékeket.
  • Null értékű típusok, amelyek az alaptípus szerint besorolt értékek mellett a null értéket is osztályozzák.
  • Típustípusok, amelyek a típusokat osztályozzák.

A nyers JSON-kimenet használatával (és/vagy a szolgáltatás $metadata definícióinak megtekintésével) a következő rekordtípusokat határozhatja meg az OData-összetett típusok megjelenítéséhez:

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
];

Figyelje meg, hogyan hivatkozik a CityType strukturált oszlopokra, és LocType hogyan LocationType jeleníti meg azokat.

Azoknak a legfelső szintű entitásoknak, amelyeket táblákként szeretne ábrázolni, a következő táblázattípusokat határozhatja meg:

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
];

Ezután frissítheti a változót SchemaTable (amelyet entitások közötti leképezések keresési táblájaként használhat) az alábbi új típusdefiníciók használatára:

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

Egy általános függvényre (Table.ChangeType) támaszkodva kényszerítheti ki a sémát az adataira, hasonlóan a korábbi gyakorlatban használthoz SchemaTransformTable . Ellentétben SchemaTransformTablea Table.ChangeType tényleges M táblatípussal argumentumként, és rekurzív módon alkalmazza a sémát az összes beágyazott típusra. Aláírása:

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

Megjegyzés

A rugalmasság érdekében a függvény táblákon és rekordlistákon is használható (így jelennek meg a táblák egy JSON-dokumentumban).

Ezután frissítenie kell az összekötő kódját, hogy a schema paramétert egyről egyre table typemódosítsa, és fel kell vennie egy hívást.Table.ChangeType Ennek részletei szintén nagyon implementációspecifikusak, ezért itt nem érdemes részletesen tárgyalni. Ez a kiterjesztett TripPin-összekötő-példa egy teljes körű megoldást mutat be, amely implementálja ezt a kifinomultabb módszert a séma kezeléséhez.