Skip to content

4.1 Delivery file

RnoldR edited this page Oct 8, 2024 · 9 revisions

De delivery.yaml file wordt ingelezen door dido_import en wordt gespecificeerd met de -d parameter gevolgd door een filenaam. De file wordt gezocht in de config directory van je projekt.

De hoofdstruktuur van deze file is dezelfde als die van [config.yaml](https://github.com/MinBZK/DiDo/wiki/3.1-Config-file), namelijk leveranciers met daaronder de projekten.

Bijvoorbeeld config.yaml:

SUPPLIERS:
  leverancier1:
    project1:
       schema_file: Bronanalyse_Leverancier1_project1
    project2:
       schema_file: Bronanalyse_Leverancier1_project2
  leverancier12:
    project1:
      schema_file: Bronanalyse_Leverancier2_project1
  leverancier3:
    project1:
      schema_file: Bronanalyse_Leverancier3_project1

Ziet er voor delivery.yaml als volgt uit:

DELIVERIES:
  leverancier1:
    project1:
       delivery_2022-Q3:
    project2:
       delivery_2022-J1:
  leverancier12:
    project1:
      delivery_2018-W23
  leverancier3:
    project1:
      delivery_2021-M9

Zoals je ziet is de struktuur is overal hetzelfde. Onder het projekt komen een of meer leveringen. Een levering begint altijd met delivery_ gevolgd door jaar en door een levering rapportageperiode.

DELIVERIES:
  leverancier:
    delivery_2023-Q2:
      code_bronbestand: LEVDATA
      levering_leveringsdatum: 2024-02-29
      data_file: s3://s3_dgdoobi_dwh_sta_prd/personeel/jopi/ftpes_productie/salaris/20240229_data.CSV
      data_check: yes
      origin:
        input: <file>

    delivery_2023-Q3:
      code_bronbestand: LEVDATA
      levering_leveringsdatum: 2024-02-29
      data_file: s3://s3_dgdoobi_dwh_sta_prd/personeel/jopi/ftpes_productie/salaris/20240229_data.CSV
      data_check: yes
      origin:
        input: <file>

    delivery_2023-Q4:
      code_bronbestand: LEVDATA
      levering_leveringsdatum: 2024-02-29
      data_file: s3://s3_dgdoobi_dwh_sta_prd/personeel/jopi/ftpes_productie/salaris/20240229_data.CSV
      data_check: yes
      origin:
        input: <file>

SUPPLIERS_TO_PROCESS: ['*']

# Indicate whether delivery contains header row or not
HEADERS:
  leverancier: no

# Definieer de kolommen waarvan de de spaties links en rechts moeten worden gestript
# voor iedere cel. Geef kolommen op als lijst:
#  - [] lege lijst: niets wordt gestript
#  - ['*']: alle kolommen worden gestript
#  - ['a', 'b', 'd']: van kolommen a, b, d worden de spaties links en rechts gestript
STRIP_SPACE:
  leverancier: ['*']

# Rename data on column base
# Conversies voor ikb_jopi: ontbrekende datums worden aangegeven door 0(0000000)
# In DWH is de conventie 29991231
# Niet nodig voor vertaaltabel
RENAME_DATA:
  leverancier:
    kalenderdag:             {"re": True, "^00000000$":"99991231", "^0$": "99991231", "^$": "99991231"}
    deeltijdfactor_in:       {"re": True, "(.*)-": "-\\1"}
    leeftijd_in_jaren:       {"re": True, "(.*)-": "-\\1"}
    aantal:                  {"re": True, "(.*)-": "-\\1"}

### Parameters for dido-import
# LIMITS faciliteert het instellen van limieten zodat getest kan worden op
# een beperkte hoeveelheid data of dat afgebroken wordt als er teveel fouten zijn gedetekteerd
LIMITS:
  max_rows: 0 # <1 = read all rows
  max_errors: 1000

# Generate statistics
STATISTICS:
  spendportaal:
    columns: ['*']
    max_categories: 100

SNAPSHOTS:
  zip: yes
  destroy_todo: yes

Deze voorbeeldleveringsfile beschrijft drie kwartalen aan data die geleverd zijn door de leverancier leverancier. Indien dido_import en dido_import gedraaid worden dan zullen deze de drie leveringen ophalen uit de s3 bucket, ze prepareren en vervolgens de file import-all-deliveries.sql aanmaken in de map work/sql die kan ingelezen worden met psql.

Na DELIVERIES volgt er een lijst van leveranciersnamen die eerder zijn gedefinieerd in config.yaml. Elke leverancier kent een of meer leveringen. Elke levering wordt gekenmerkt door delivery_ gevolgd door een levering rapportageperiode gevolgd door de parameters die die levering definieren. Bijvoorbeeld delivery_2023-Q3: betekent dat er een levering is voor het derde kwartaal van 2023. Daaronder worden een aantal parameters van die specifieke levering genoemd.

Opties voor een levering

data_file

de naam van de datafile. Als die voorafgegaan wordt door s3:// dan wordt hij gezocht in de s3 bucket. Als het geen absolute padnaam is dan wordt hij gezocht onder root_directory/data/leverancier/data_file

data_check

yes = de data wordt gecontroleerd, no = dus niet. Indien input gelijk is aan <table> (zie verderop) dan is data_check altijd no

data_encoding

Naam van erkende ISO encoding, bijvoorbeeld utf8 of CP850

delimiter

Scheidingsteken van de in te lezen .csv file. Dit is standaard ';' maar hier kan de gebruiker dat veranderen als exotische scheidingstekens zoals een komma worden gebruikt.

delivery_type

Mutatie heeft al gewerkt maar is op dit moment niet goed getest. Gebruik op eigen risico

Specifeert het type van de levering met additionele parameters:

  • mode: deze is insert of mutation
  • mutation_key: een unieke sleutel voor een record; hij is uniek voor een geschiedenis van een record. Er bestaat er echter maar maximaal een die nu geldig is, als het record is verwijderd dan is er geen record met dit recordnummer dat geldig is
  • mutation_instructions: indien de mode mutation is, dan is dit een lijst met de namen van de kolommen die het type van de mutat ie aangeven. Bijvoorbeeld voor postcodes is dit een kolom type waarin insert, delete of mutate de opties van de mutatie zijn. Voor andere api's kan dit een andere betekenis hebben.
  • store_in_database: indien automatic dan worden veranderingen direkt in de database opgeslagen door DiDo. Bij 'manual' moet de gebruiker zelf de file import-all-deliveries.sql inlezen met psql om de gegevens op te slaan in de database. manual is de default waarde.

origin

Geeft aan waar de data vandaan komt. Kent een aantal opties:

  • input: <file>, <table> of <api>
  • source: de naam van de bron
  • table_name ???: naam van de table indien input is <table>
  • voor <api> gelden nog een aantal opties die de toeging tot de api regelen. Bij vrijwel alle API's dient er ingelogd te worden. De specifieke credentials voor die API moet worden gespecificeerd in de .env file in de config directory van het projekt.
    • url_account: een account waar de credentials te vinden zijn
    • url_delivery: het url waar de gegevens kunnen worden opgehaald
    • start_date: datum vanaf wanneer de gegevens kunnen worden opogehaald in YYYY-MM-DD formaat

Niet altijd is het gewenst de leveringen van alle leveranciers op te halen gedurende een import run. Dit kan worden aangegevens met de optie SUPPLIERS_TO_PROCESS: [<lijst van te verwerken leveranciers>]. Als de lijst alleen '*' bevat is (['*']) dan worden alle leveranciers verwerkt.

Extra bewerkingen tijdens inlezen Data

Hoewel DiDo het "binnensluizen" van ruwe data "as is" in de ODL laag van de database betreft, kunnen er toch een paar modificaties door de gebruiker worden gespecificeerd. Dit betreft kleine, reproduceerbare wijzigingen die de verdere verwerking van de data in Postgres sterk vereenvoudigd.

HEADERS

HEADERS: 
  <leverancier>: yes|no

Standaard wordt een .csv file als input verwacht met kolomnamen in de eerste rij. Indien voor die leverancier geen headers worden meegeleverd dan leidt DiDo die af uit de definitie van de data zoals die is opgeslagen in postgres. Als er kolommen te weinig of teveel zijn of zijn omgewisseld dan merkt DiDo dat niet. Ergens in de verwerking door DiDo of Postgres worden in zo'n geval nogal ondoorgrondelijke foutmeldingen gegenereerd. Probeer zo'n situatie te voorkomen.

STRIP_SPACE

STRIP_SPACE:
  leverancier: ['*']

Deze optie strips spaties links en rechts van alle data weg van de aangegeven kolommen: ['*'] betekent van alle kolommen.

Decimale conversie

Niet iets dat de gebruiker kan specificeren, dit gebeurt automatisch als in de meta file in schemas/leverancier bij Bronbestand decimaal een komma is gespecificeerd:

Bronbestand decimaal;,

De achterliggende reden is dat Postgres op geen enkele manier een komma accepteert en ook niet wil konverteren. Daarom konverteert DiDo automatisch alle real-type velden zoals real, numeric en double precision. Dido doet geen konversie van duizendtal scheidingstekens. Deze leiden tot een foutmelding van psql als geprobeerd wordt een file met duizendtal schedingstekens in te lezen.

RENAME_DATA

RENAME_DATA:
  leverancier:
    kalenderdag:             {"re": True, "^00000000$":"99991231", "^0$": "99991231"}
    leeftijd_in_jaren:       {"re": True, "(.*)-": "-\\1"}
    aantal:                  {"re": True, "(.*)-": "-\\1"}
    <date>:                  {"00000000":"29991231", "0": "29991231"}

Deze optie maakt het mogelijk om data te wijzigen die anders tot fouten zouden leiden bij het inlezen door Postgres. P-Direkt levert data aan waarin in een datum veld 8 nullen, of 1 nul betekent dat de data ver in de toekomst ligt In alle gevallen leidt dat tot het afbreken van het inleesproces door Postgres omdat er een ISO datum wordt verwacht. Om dat te voorkomen worden sommige datumkolommen gerenamed naar 99991231.

Ook worden data aangeleverd met een min(-) teken aan het eind van het getal in plaats van ervoor. Met {"re": True, "(.*)-": "-\\1"} wordt het min-tekent voor het getal gezet. In beide voorbeelden wordt gebruik gemaakt van regular expressions.

Indien een datatype tussen <...> wordt gezet dan worden alle kolommen van dat datatype geconverteerd. In de logfile valt terug te lezen welke kolommen tot dat type behoren en worden geconverteerd.

STATISTICS

Genereert een aantal statistieken op de data uit. Voor numerieke data worden zaken als gemiddelde en standaard deviatie uitgerekend, voor alle data behalve reals worden frekwenties berekend indien het aantal categorien klein genoeg is. Het maximaal aantal categorien wordt met max_categories aangegeven. De statistieken worden berekend over alle kolommen in de columns sektie. Als die leeg is, dan worden er geen statistieken berekend, '*' betekent alle kolommen.

# Generate statistics
STATISTICS:
  spendportaal:
    columns: ['*']
    max_categories: 100

Waarschuwing: het berekenen van statistieken kan bij grote files soms meer tijd kosten dan het inlezen en controleren van de data. Bijvoorbeeld het inlezen van de postcodetabel met ongeveer 10 miljoen records en 30 kolommen duurt ongeveer 1 uur, het berekenen van de statistieken kan in dat geval meer dan 2 uur kosten.

Lege cellen worden NULL bij niet-tekst

Voor alle types behalve tekst wordt afgedwongen dat ze NULL worden in de postgres database. Dat gebeurt met SQL instructie FORCE NULL bij het inlezen van de .csv datafile.

Voor tekst types betekent een leeg veld een veld met een lege string.

Volgorde van de bewerkingen

Dido_import verwerkt alle gegevens als tekst. Pas tijdens het inlezen door Postgres probeert Postgres de tekst als het desbetreffende datatype in te lezen: date, integer, floating point, etc. De volgorde waarin de controles worden uitgevoerd zijn:

  1. Controle op de headers
  2. Alle spaties links en rechts wegstrippen indien dat gespecificeerd is
  3. Konversie van decimale komma naar decimale punt indien dat aan de orde is
  4. Data renaming
  5. Lege velden van niet tekst kolommen worden geconverteerd naar NULL

LIMITS

  • max_rows: n betekent dat de eerste n rijen worden ingelezen. Handig voor het testen van grote files. n = 0 betekent dat alles wordt ingelezen.
  • max_errors: 1000 geeft aan dat als er meer dan 1000 fouten worden ontdekt dat de bewerking wordt afgebroken. Als er zoveel fouten optreden dan is er meestal iets misgegaan bij het datatype o.i.d. Ook worden alle fouten gelogd. Het loggen van miljoenen fouten kan uren, zo niet dagen duren. En nee, DiDo hangt dan niet.

Bestaande leveringen negeren

Indien een levering reeds bestaat in de database dan wordt deze genegeerd. De levering_rapportageperiode wordt gebruikt om te kijken of er al een levering bestaat. Dat is handig want op die manier kunnen aan een bestaande delivery.yaml telkens nieuwe leveringen worden toegevoegd zonder dat de oude leveringen worden overschreven en zelfs zonder dat de data voor de oude leveringen hoeft te bestaan.

Wanneer de gebruiker toch leveringen wil controleren omdanks dat deze al in de database is opgeslagen dan kan dat door de ENFORCE_parameter te gebruiken. Indien die op yes staan dan wordt de controle uitgevoerd.

ENFORCE_IMPORT_IF_TABLE_EXISTS: yes

Waarschuwing: de gebruiker moet er zelf voor zorgen dat de oude leveringen worden verwijderd met behulp van dido_remove.py voor specifieke leveringen of door eerst alle data weg te halen, deze opnieuw op te bouwen met create_tables.py waarna de bewuste leveringen worden ingelezen met psql.

Clone this wiki locally