Vad som landar i målmiljön
De flesta automatiseringsverktyg levererar rader. PDQ levererar ett beskrivet, begränsat och klassificerat schema — och raderna.
Tabellerna i din måldatabas genereras från samma metadata som driver laddningen. Det är därför de kommer dokumenterade i stället för att behöva dokumenteras: kommentarer, primärnycklar, främmande nycklar, unika villkor, kategorietiketter och känslighetsetiketter emitteras av generatorn, utifrån deklarationer som gjorts en gång uppströms. Ingen skriver ett COMMENT ON COLUMN-skript. Ingen taggar om PII i katalogen i efterhand.
Den här sidan beskriver vad som faktiskt hamnar i målet, var varje del kommer ifrån och hur du får ut det igen.
Deklarerat en gång, materialiserat överallt
Ett fält beskrivs på ett ställe — i källfilens datakontrakt eller i modellattributet — och den beskrivningen följer med hela vägen ned.
| Du deklarerar | Var du deklarerar det | Vad som hamnar i målet |
|---|---|---|
description | Källfilsfält, modellattribut, modellobjekt | Kolumn- och tabell-COMMENT i genererad CREATE TABLE |
keyFieldIndicator + keyOrder | Källfilsfält | Primärnyckel på publiceringstabellen; unikt villkor på core-tabellen |
Relation (toObject, toAttribute, relationType) | Modell | Främmande nyckel, barn → förälder |
fieldDomain | Källfilsfält, via Field Categorization | Kategorietikett på kolumnen, och på barntabeller som ärver nyckeln |
sensitive | Källfilsfält | Känslighetsetikett, och en kolumnmask där plattformen stödjer det |
validFrom | Källfilsfält | SCD Type 2-versionskolumn; giltighetsperioden i den historiserade core-modellen |
dataType | Källfilsfält | Kolumntypen, mappad till målplattformens egen typ |
Ändra deklarationen, generera om, och målet ändras med den. Beskrivningen i konsolen, kommentaren på kolumnen och definitionen i repositoryt kan inte glida isär, eftersom det bara finns en av dem.
Struktur — nycklar och villkor
Villkor genereras från metadata som redan finns. En affärsnyckel är redan deklarerad för att deduplicering och upserts ska fungera; en relation är redan deklarerad för att modellen ska hänga ihop. Generatorn gör databasobjekt av båda i stället för att låta dem förbli plattformsintern kunskap.
| Objekt | Genereras från | Var det hamnar |
|---|---|---|
| Unikt villkor | Affärsnycklar | Core-tabeller — inline där plattformen kräver det, annars ALTER … ADD |
| Främmande nyckel | Relationsmetadata | Barn → förälder, deduplicerat |
| Primärnyckel | Affärsnycklar, med __fileKey inkluderad | Publiceringstabeller |
Alla tre är påslagna som standard. För att behålla utdata som före 3.2, sätt ENABLE_CORE_UNIQUE, ENABLE_FOREIGN_KEY och ENABLE_PUBL_PRIMARY_KEY till 0.
DEVELOPMENT-vägen emitterar endast strukturella kolumnändringar — CREATE TABLE IF NOT EXISTS och ALTER ADD/DROP COLUMN. Kommentarer samt DDL för unika och främmande nycklar är enbart definitioner, och dubbletter av körbara satser dedupliceras i granskningsspåret. En utvecklingsdriftsättning skriver därför inte om dekoration den inte ändrat.
Dokumentation — kommentarer redan vid skapandet
Kolumn- och tabellkommentarer emitteras inuti CREATE TABLE på Snowflake och Databricks, inte påklistrat i efterhand. En tabell är dokumenterad från det ögonblick den existerar, så det finns inget fönster där den existerar odokumenterad.
- Kommentarstexten är den beskrivning som skrivits på källfilsfältet, modellattributet eller modellobjektet.
- Staging-landningstabeller bär fasta tekniska beskrivningar på
rowId,fileName,VARIANT-kolumnen ochloadedTs— så att även rörmokeriet förklarar sig självt. - Apostrofer i beskrivningar escapas på alla kommentarsvägar, så en beskrivning som lyder
kundens regionbryter inte satsen.
Samma beskrivningar renderas i konsolens genererade dokumentation och i de definitioner som SQL Generator-API:et producerar. En källa, tre ytor.
Klassificering — etiketter och maskering
Klassificering är inte en separat katalogiseringsövning som sker efter att datalagret byggts. Det är en egenskap hos fältet, och det tillämpas på målet som en del av att tabellen byggs.
| Begrepp | Konfiguration | Emitteras som |
|---|---|---|
| Kategorietikett | TAG_NAME, med en standardkategori | En etikett på kolumnen som bär dess fieldDomain |
| Känslig data | SENSITIVE_TAG_NAME, SENSITIVE_TAG_VALUE | En känslighetsetikett på varje fält märkt sensitive |
| Maskering | Plattformsberoende | En maskeringspolicy på Snowflake, dynamic data masking i T-SQL-familjen, SECURITY LABEL på PostgreSQL — och ingenting på Databricks, där sensitive bara ger en etikett |
På Databricks emitteras klassificering som SET TAGS, eftersom det är den funktion Unity Catalog faktiskt läser; ingen mask genereras där. Kategorier läggs till publicerade tabeller och refererar enbart till föräldratabellen. Hela bilden per plattform finns i Skillnader mellan målplattformar.
TAG_NAME, SENSITIVE_TAG_NAME och SENSITIVE_TAG_VALUE har standardvärden, och standardvärdena är lätta att leva med av misstag. Bestäm det schema som matchar er katalogs konventioner före den första genereringskörningen, inte efter att några hundra tabeller bär fel etikettnamn.
Klassificering följer nyckeln nedåt i hierarkin
När en hierarkisk källa normaliseras till en uppsättning tabeller bär en barntabell de affärsnycklar som ärvts från förfädernas nivåer. Dessa nyckelkolumner kommer med sina domänetiketter fästa: en klassificering deklarerad på en föräldranivå tillämpas på barntabellen där nyckeln landar.
Arvsreglerna är medvetet konservativa:
- Förfäder gås igenom närmast först, och fyller endast luckor.
- En domän deklarerad på tabellens egen nivå vinner alltid.
- Varje alias emitteras en gång.
- Endast nyckelfält ärvs.
Den praktiska effekten är att en kolumn som klassificerats en gång — säg ett personnummer som används som affärsnyckel — förblir klassificerad överallt den bärs vidare, utan att någon behöver hålla reda på vart den kopierats.
Vad varje plattform faktiskt upprätthåller
Styrning emitteras per plattform, med den funktion plattformen erbjuder. Vad det innebär i praktiken skiljer sig åt:
| Mål | Villkor | Kommentarer | Klassificering |
|---|---|---|---|
| Snowflake | Unika, primär- och främmande nycklar genereras, alla NOT ENFORCED | COMMENT inuti CREATE TABLE | Etiketter; QUERY_TAG bär körningen |
| Databricks | Inga emitteras — mallarna för UNIQUE, PK och FK är medvetet utelämnade | COMMENT inuti CREATE TABLE | SET TAGS i Unity Catalog |
| SQL Server / Fabric | Upprätthållna unika villkor; främmande nycklar genereras men upprätthålls inte | Extended properties på SQL Server; bärs inte in på Fabric | Extended properties |
| Synapse | Unikt NOT ENFORCED; inga främmande nycklar — dedikerade pooler stödjer dem inte | Bärs inte in | Extended properties |
| PostgreSQL | Upprätthållna unika och främmande nycklar, sekvenser | Endast base-lagret | Sidotabell |
Databricks, Snowflake och Synapse emitterar inga upprätthållna UNIQUE, och endast PostgreSQL upprätthåller en främmande nyckel. Dubbletter kan ändå inte nå core — deduplicering på affärsnyckeln ingår i det genererade laddningsmönstret — så det den saknade begränsningen kostar är skyddet mot skrivningar som går förbi den laddningsvägen. Se Skillnader mellan målplattformar för hela genomgången.
Varje sats bär jobbet som utfärdade den
Metadata fångas inte bara om flödet — den skjuts in i målets egna observerbarhetsytor. Varje sats som workern skickar bär den arbetsenhet den tillhör: app, workerversion, typ (dwa / dm / qpi), jobb, steg, körning, kö, omförsök, plus stegets egna objekt-, attribut- och relationsidentifierare. Ingenting behöver konfigureras, och ett statiskt QUERY_TAG- eller APP-värde som ni redan satt bevaras i stället för att kastas.
| Mål | Den inbyggda funktion etiketten hamnar i |
|---|---|
| Snowflake | QUERY_TAG, som JSON |
| Databricks | user_agent_entry |
| PostgreSQL | application_name (63 bytes gräns) |
| SQL Server / Synapse / Fabric | ODBC APP → program_name |
| Alla mål | Inledande sqlcommenter-kommentar |
Kommentaren emitteras i sqlcommenter-form — sorterade, procentkodade key='value'-par som verktyg för databasobserverbarhet redan känner igen.
Varför det spelar roll bortom felsökning: en fråga i målets egen historik kan kopplas tillbaka till den flödeskörning som utfärdade den. Det är den join-nyckel som kostnadsfördelning har saknat — förbrukning registrerad av datalagret på ena sidan, deklarationen som orsakade den på den andra.
Metadata fångas överallt, och går att agera på
Varje steg skriver sin egen post, och varje post är adresserbar — i konsolen och via API:et.
| Vad som fångas | Var det fångas | Vad du kan göra med det |
|---|---|---|
| Granskningslogg för leveranser | Landningszonen, per fil | Spåra en leverans genom Landing → Raw → Trusted → Published |
| Profileringsstatistik | Profile-zonen, per källfil | Se typöverensstämmelse, null-andelar, fördelningar och schemaavvikelser |
| Laddningsstatistik | Per källfil och per objekt | Rader som stagats och infogats, per körning |
| Publiceringsgranskning | Per publicering | Bekräfta att varje publicering landat i sin måltabell |
| Resultat från kvalitetskontroller | Per kontroll, nyckel (qpi, runDttm) | Skilja en regel som fångat något från en kontroll som själv var trasig |
| Granskningslogg för åtgärder | Per konsolåtgärd | Vem som gjorde vad, i vilken roll, på vilken sida och när |
| Härkomst | Härledd från levande metadata | System → källfiler → modeller → exporter |
Två designval gör detta möjligt att agera på i stället för bara närvarande:
- En misslyckad laddning är synlig, inte frånvarande. Granskningsloggning i landningszonen försöker om fem gånger, skickar sedan meddelandet till kön
<zone>-parkedoch rapporterar fel. Parkerade meddelanden försöks inte om automatiskt — bevaka de köerna. - En kvalitetskörning läses som data, inte som ett enda godkänt/underkänt. Varje kontroll registrerar sitt eget tillstånd och resultat. En kontroll vars SQL kördes men vars test underkändes är
CompletedmedresultState=fail; en kontroll vars SQL kastade fel ärFailedmed det verkliga felet och stackspårningen.
Att få ut det — API:er och OpenLineage
Ingenting av detta är inlåst i plattformen. Det är metadata, och metadata går att exportera.
REST-API
AME:s REST-API är samma gränssnitt som konsolen och generatorerna läser — det finns ingen privilegierad intern kanal. v3-familjen levererar konfiguration, struktur, scheman, loggar och härkomst, med /api/v3.2 för
objektnivågenerering.
/api/v4 är där dataproduktkontraktet bor. En dataproduktspecifikation är /api/v4
data product contract — de två är samma sak under två namn. Det är en separat familj snarare än en
efterträdare till v3: v3 beskriver hur plattformen är konfigurerad och vad den gjorde, v4 beskriver
vad som levereras.
- Field Categorization-endpoints hämtar, skapar och uppdaterar domänklassificeringar för fält, med full versionsspårning.
- Log-by-date-endpoints och endpoints för publiceringsgranskning exponerar den operativa historiken.
- Källfils-endpoints returnerar hela datakontraktet, inklusive
listLevels,targetNormalizationoch Published-scheman. - Definitionsgenerering via SQL Generator-API:et returnerar den genererade DDL:en, så att en definition kan diffas i CI innan den driftsätts.
Källfilens datakontrakt förhandlas i stället för att antas — försöks först på v3.2, sedan v3.1, sedan v3.
OpenLineage
PDQ emitterar OpenLineage-händelser, så att härkomst hamnar i den katalog eller observerbarhetsplattform ni redan kör i stället för enbart i PDQ-konsolen.
- Start- och sluthändelser för alla körningar, från SQL-exekveringsmotorn.
- Föräldrajobbshändelser från QPI-kvalitetskontroller, så att en kontroll kopplas till den körning den hör till.
- Härkomst på attributnivå tillgänglig som ett detaljerat alternativ, vid sidan av händelser på datamängdsnivå.
- Published-mönster, trusted-datamängder och PDQ-vyer representeras alla, med namnrymder upplösta per zon.
Den praktiska konsekvensen: katalogen ni redan kör behöver inte ett eget flöde för att veta varifrån en kolumn kommer.
Vad detta ersätter
| Det vanliga upplägget | Med PDQ |
|---|---|
| Ett katalogiseringsprojekt som taggar PII efter att datalagret byggts | Etiketten är en egenskap hos fältet, tillämpad när tabellen skapas |
| En dataordlista som glider ifrån databasen | Kommentaren i databasen är beskrivningen i repositoryt |
| Villkor dokumenterade i ett modelleringsverktyg och aldrig driftsatta | Nycklar och relationer genererade som databasobjekt |
| Härkomst underhållen för hand, eller härledd genom att tolka SQL | Härkomst emitterad som OpenLineage-händelser av körningen själv |
| Datalagerkostnader fördelade på gissningar | Varje fråga i målets historik bär jobbet som utfärdade den |
Styrning slutar vara ett parallellt projekt vid sidan av flödet och blir en egenskap hos flödet.
Nästa steg
- Skillnader mellan målplattformar — vad var och en av de sex stödda motorerna faktiskt upprätthåller, bär och inte klarar
- Kapabiliteter för datahantering — hela kapabilitetslistan, inklusive styrning och metadata
- DWA-lagret — styrningsflaggorna på fältnivå i detalj
- Data Warehouse Automation — att modellera nycklarna och relationerna som villkoren kommer från
- Data Lake Service — att deklarera klassificering på källfilsfälten
- Vad som ändras i 3.2 — versionen som gjorde styrning genererad i stället för manuell