-
Notifications
You must be signed in to change notification settings - Fork 0
4.1 Delivery file
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.
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
yes = de data wordt gecontroleerd, no = dus niet. Indien input
gelijk is aan <table>
(zie verderop) dan is data_check
altijd no
Naam van erkende ISO encoding, bijvoorbeeld utf8
of CP850
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.
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
ofmutation
- 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 kolomtype
waarininsert
,delete
ofmutate
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 fileimport-all-deliveries.sql
inlezen metpsql
om de gegevens op te slaan in de database.manual
is de default waarde.
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.
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:
<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:
leverancier: ['*']
Deze optie strips spaties links en rechts van alle data weg van de aangegeven kolommen: ['*'] betekent van alle kolommen.
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:
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.
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.
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.
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:
- Controle op de headers
- Alle spaties links en rechts wegstrippen indien dat gespecificeerd is
- Konversie van decimale komma naar decimale punt indien dat aan de orde is
- Data renaming
- Lege velden van niet tekst kolommen worden geconverteerd naar NULL
- 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.
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
.