CASUS eenvoudige CBS datamart

De CASUS is het ophalen van opendata uit het CBS register om vervolgens daarop enkele ETL's te definieeren voor de dimensies en vervolgens een FACT-ETL maken met lookup's naar deze dimensies.

Inleiding: Welk proces gaan we volgen, welke stappen en deze hieronder markeren.

Navigator

STAP 1 : CBS opendata

CBS is de bron van veel opendata. GRIP heeft het speciale commando CBS_OPENDATA ontwikkeld voor het ophalen de inhoudsopgave van wat CBS aan data te bieden heeft. Deze inhoudsopgave wordt in de gelijkgenaamde tabel 'CBS_OPENDATA' opgeslagen welke eenvoudige met een sql-query uit te vragen is. Iedere CBS-opendata-set kan opgehaald worden via zijn IDENTIFIER. In onderstaande figuur zie je de data-sets van query

**NB: de sql-syntax die hieronder weergegeven is, is voor een sqlserverdatabase.

Voer het onderstaand command uit:

   CBS_OPENDATA

Wanneer het commando klaar is, kan met onderstaande de inhoudsopgave van wat CBS aan opendata geschikbaar heeft, weergegeven worden:

select top 100 Identifier, title, updated  from xxx.CBS_OPENDATA where lower(title) like '%ziek%'    

Wanneer je geinteresseerd bent in de dataset 'Ziekenhuisopnamen ... ' met identifier 84067NED, dan kan deze dataset geladen worden met de GRIP-call 'CBS_OPENDATA_READ 84067NED'. Er wordt een tabel CBS_OPENDATA_84067NED gecreeerd waar deze dataset in opgeslagen wordt.

Voer het onderstaande commando uit:

   CBS_OPENDATA_READ 84466NED

Wanneer dit commando is uitgevoerd, is er een tabel gecreeerd op basis van deze data, met als tabelnaam CBS_OPENDATA_84067NED. Deze tabel kan als bron dienen voor het datawarehouse.

   select top 100 * from xxx.CBS_OPENDATA_84466NED ( sqlserver )

   select * from xxx.CBS_OPENDATA_84466NED limit 100 ( postgresql )
  • xxx. staat voor currurrent-schema

Navigator

STAP 2 : de bron

Voor onze demo gaan we opendata ophalen van CBS met als identifier : 84466NED.. Het betreft data over "Zelfstandigen; inkomen, vermogen, kenmerken Zelfstandigen;"

select * from xxx.CBS_OPENDATA where identifier = '84466NED'

Busy...
[SS_boss,grip_parse,INFO]  tonen resultaat van query:  select * from   xxx.CBS_OPENDATA where identifier = '84466NED' 

-------------------------------------------------------------------- dataframe from SS_boss
select * from   grip.CBS_OPENDATA where identifier = '84466NED' 
  ( **  rownorow : voor aan en uitzetten van regelnummers ,  clipboard : voor data via het clipboard beschikbaar stellen ) 
---------------------------------------------------------------------
               UPDATED   ID IDENTIFIER                                        TITLE               SHORTTITLE                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             SHORTDESCRIPTION                                                                                             SUMMARY             MODIFIED     METADATAMODIFIED REASONDELIVERY EXPLANATORYTEXT OUTPUTSTATUS SOURCE LANGUAGE CATALOG FREQUENCY         PERIOD                                                                                                                                                                                                                                                                                                                             SUMMARYANDLINKS                                           APIURL                                           FEEDURL                                                                                                       DEFAULTPRESENTATION                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       DEFAULTSELECTION      GRAPHTYPES  RECORDCOUNT  COLUMNCOUNT SEARCHPRIORITY
0  2020-11-03T02:00:00  741   84466NED  Zelfstandigen; inkomen, vermogen, kenmerken  Zelfstandigen; welvaart  \nDeze tabel bevat gegevens over het inkomen en vermogen van zelfstandigen. Er wordt onderscheid gemaakt tussen enerzijds de personen voor wie het voornaamste inkomen wordt gegenereerd uit werkzaamheden als zelfstandige, en anderzijds alle personen met inkomen uit werkzaamheden als zelfstandige. De cijfers in deze tabel zijn uitgesplitst naar type zelfstandige, economische activiteit, geslacht, leeftijd, migratieachtergrond, positie in het huishouden, en naar inkomens- en vermogensgroepen.\n\nAlle statistieken in deze tabel zijn op persoonsniveau, ook de vermogens; (bedrijfs)vermogens zijn bepaald per huishouden, en worden toegekend aan alle personen in het huishouden als een maat voor de welvaart. Peildatum van doelpopulatie en vermogen is 1 januari van het verslagjaar. Voor de oudere jaargangen 2007 t/m 2010 is de peildatum van vermogen 1 januari van het jaar volgend op het verslagjaar.\n\nVoor het bepalen van de SBI van zelfstandigen wordt gebruik gemaakt van het Algemeen Bedrijvenregister (ABR). Het ABR heeft in de periode 2007-2011 met diverse trendbreuken te maken gehad. Dit leidt in deze tabel tot een forse daling van het aantal zelfstandigen in de financiƫle dienstverlening (K) in 2010. Bij het vergelijken van de cijfers naar SBI is daarom voorzichtigheid geboden.\n\nGegevens beschikbaar vanaf: 2007. \n\nStatus van de cijfers: \nDe cijfers in deze tabel zijn voorlopig. \n\nWijzigingen per 3 november 2020:\nDe cijfers over 2018 zijn bijgewerkt, en de cijfers over 2019 zijn toegevoegd.\nAlle jaargangen zijn nog voorlopig, omdat er wordt gewerkt aan een verbetering van het aanmerkelijk belang. \n\nWanneer komen er nieuwe cijfers?\nDe nieuwe cijfers over 2020 komen in december 2021 beschikbaar.\nDe gereviseerde cijfers over de periode 2006 t/m 2019 komen in het eerste kwartaal van 2021 beschikbaar.\n  Inkomen en vermogen van zelfstandigen\nType zelfstandige, bedrijfstak, kenmerken van zelfstandigen  2020-11-03T02:00:00  2020-11-03T02:00:00  Actualisering                     Regulier   CBS.       nl     CBS   Perjaar  2007 t/m 2019  Inkomen en vermogen van zelfstandigen<br />Type zelfstandige, bedrijfstak, kenmerken van zelfstandigen<br /><a href="http://opendata.cbs.nl/ODataApi/OData/84466NED">http://opendata.cbs.nl/ODataApi/OData/84466NED</a><br /><a href="http://opendata.cbs.nl/ODataFeed/OData/84466NED">http://opendata.cbs.nl/ODataFeed/OData/84466NED</a>  https://opendata.cbs.nl/ODataApi/OData/84466NED  https://opendata.cbs.nl/ODataFeed/OData/84466NED  ts=1603282320817&graphtype=Table&r=TypeZelfstandige&k=Topics&t=Geslacht,BedrijfstakkenBranchesSBI2008,Kenmerken,Perioden  $filter=((TypeZelfstandige eq '2021380') or (TypeZelfstandige eq '2021430') or (TypeZelfstandige eq '2021420') or (TypeZelfstandige eq '2021400') or (TypeZelfstandige eq '2021390') or (TypeZelfstandige eq '2021393') or (TypeZelfstandige eq '2021410')) and ((Geslacht eq 'T001038')) and ((BedrijfstakkenBranchesSBI2008 eq 'T001081')) and ((Kenmerken eq 'T009002')) and ((Perioden eq '2019JJ00'))&$select=TypeZelfstandige, Geslacht, BedrijfstakkenBranchesSBI2008, Kenmerken, Perioden, Zelfstandigen_1, MediaanInkomenAlsZelfstandige_5, MediaanGestandaardiseerdInkomen_7, MediaanVermogen_9, Zelfstandigen_11, MediaanInkomenAlsZelfstandige_15, MediaanGestandaardiseerdInkomen_17, MediaanVermogen_19  Table,Bar,Line       597246           25              2
--------------------------------------------------------------------

Ready ......(2.7)...........

Inlezen van de dataset kan met onderstaand commando:

   CBS_OPENDATA_READ 84466NED

na bovenstaande CALL is een tabel gecreerd, genaamd CBS_OPENDATA_84466NED
de identifier van de dataset wordt de prefix van de tabel

   select top 100 * from xxx.CBS_OPENDATA_84466NED  

Deze dataset gaan we gebruiken als bron voor een datamart met dimensies en een fact-tabel.

In het navolgende laten we zien hoe eenvoudig we een datamart van deze bron maken, compleet met FLOW.

STAP 3 : de dimensies

Doel: Enkele DIMENSIE-VIEWS maken voor het stermodel

  • de xxx. staat voor de current-login-schema zoals in de connectie-file grip_con.dat is opgegeven.
    Deze xxx. behoeft niet in de ETL-call gebruikt te worden, wel in de view.
  • SOURCE : de naam van de bron-view of bron-tabel ( zonder xxx. )
  • TARGET : de naam van de target-tabel. Indien de target tabel niet bestaat, wordt hij gecreeerd
    op basis van de structuur van de SOURCE
  • MERGE_KEYS : de unique key van de SOURCE/TABLE. Indien een van de attributen een null-value bevat of wanneer de keys duplicaten kent, genereert GRIP een error en stagneert de ETL / FLOW.

We gebruiken hier de actualize_t2 functie waarmee het databeeld van de source-view DIM_TYPEZELFSTANDIGE_V type-2 geactualiseerd wordt. Dat betekent dat deze dimensie met historie wordt opgebouwd. Middels de attributen date_created en date_deleted, kan een selectie op pijldatum, terug in de tijd, genomen worden: het zgn. tijdreizen.

Selecteer 1 of meerdere regels en click op {execute}-button .. De geselecteerde regels worden uitgevoerd. De meeste commando's staan op 1 regel en middels {ctrl-enter} worden de regels, waar de cursor op knippert, uitgevoerd.

drop view xxx.DIM_TYPEZELFSTANDIGE_V

create view xxx.DIM_TYPEZELFSTANDIGE_V
as 
   select   TYPEZELFSTANDIGE, sum(1) aantal 
   from xxx.CBS_OPENDATA_84466NED
    group by TYPEZELFSTANDIGE 

    actualize_t2('| SOURCE DIM_TYPEZELFSTANDIGE_V | TARGET DIM_TYPEZELFSTANDIGE| MERGE_KEYS TYPEZELFSTANDIGE | ') 

de inhoud van de tabel kan bekenen worden met

  • select * from xxx.DIM_TYPEZELFSTANDIGE
  • browse DIM_TYPEZELFSTANDIGE
drop view xxx.DIM_GESLACHT_V

create view xxx.DIM_GESLACHT_V
as
   select   GESLACHT , sum(1) aantal 
   from xxx.CBS_OPENDATA_84466NED
    group by GESLACHT 

    actualize_t2('| SOURCE  DIM_GESLACHT_V | TARGET  DIM_GESLACHT |  MERGE_KEYS GESLACHT | ') 
drop view xxx.DIM_KENMERKEN_V

create view xxx.DIM_KENMERKEN_V
as
   select   KENMERKEN , sum(1) aantal 
   from xxx.CBS_OPENDATA_84466NED
    group by KENMERKEN 

   actualize_t2('| SOURCE  DIM_KENMERKEN_V | TARGET  DIM_KENMERKEN |  MERGE_KEYS KENMERKEN | ') 
drop view xxx.DIM_PERIODEN_V

create view xxx.DIM_PERIODEN_V
as
   select   PERIODEN , sum(1) aantal 
   from xxx.CBS_OPENDATA_84466NED
    group by PERIODEN 

    actualize_t2('| SOURCE  DIM_PERIODEN_V | TARGET  DIM_PERIODEN |  MERGE_KEYS  PERIODEN | ') 
drop view xxx.DIM_INKOMEN_V

create view xxx.DIM_INKOMEN_V
as
   select   GEMIDDELDPERSOONLIJKINKOMEN_2 INKOMEN, sum(1) aantal 
   from xxx.CBS_OPENDATA_84466NED
   where GEMIDDELDPERSOONLIJKINKOMEN_2 is not null
    group by GEMIDDELDPERSOONLIJKINKOMEN_2 

    actualize_t2('| SOURCE  DIM_INKOMEN_V | TARGET DIM_INKOMEN |  MERGE_KEYS  INKOMEN | ') 

STAP 4 : de fact

Creatie van de FACT-view voor koppeling met de Dimensies.
desgewenst kunnen nog indexen en foreignkeys aangebracht worden ...

drop view xxx.FACT_84466NED_V

create view xxx.FACT_84466NED_V
as
select distinct 
       coalesce (a.id,-1) DIM_TYPEZELFSTANDIGE_id
,      coalesce (b.id,-1) DIM_GESLACHT_id
,      coalesce (c.id,-1) DIM_KENMERKEN_id
,      coalesce (d.id,-1) DIM_PERIODEN_id
,      coalesce (e.id,-1) DIM_INKOMEN_id
from ( select  * from xxx.CBS_OPENDATA_84466NED ) x
left join xxx.DIM_TYPEZELFSTANDIGE a on ( a.TYPEZELFSTANDIGE = x.TYPEZELFSTANDIGE ) 
left join xxx.DIM_GESLACHT b         on ( b.GESLACHT  = x.GESLACHT ) 
left join xxx.DIM_KENMERKEN c        on ( c.KENMERKEN = x.KENMERKEN ) 
left join xxx.DIM_PERIODEN d         on ( d.PERIODEN  = x.PERIODEN ) 
left join xxx.DIM_INKOMEN  e         on ( e.INKOMEN   = x.GEMIDDELDPERSOONLIJKINKOMEN_2 ) 


    actualize_t2('| SOURCE  FACT_84466NED_V | TARGET FACT_84466NED |  MERGE_KEYS DIM_TYPEZELFSTANDIGE_id,DIM_GESLACHT_id,DIM_KENMERKEN_id,DIM_PERIODEN_id,DIM_INKOMEN_id | ') 

Middels onderstaande commando kan de fact-table bekeken worden. NB, indien je de view uitbreidt met extra kolommen zal de ETL-sql die GRIP genereert, fout gaan. Door SHOWRES

  • browse FACT_84466NED

Extra parameters SHOWRES en SHOWCODE kunnen gebruikt worden :

bv: actualize_t2('| SOURCE DIM_INKOMEN_V | TARGET DIM_INKOMEN | SHOWRES | SHOWCODE | MERGE_KEYS INKOMEN | ')

  • SHOWRES : de log-gegevens worden getoond.
  • SHOWCODE : alle gegenereerde code wordt getoond.

STAP 5 : de flow

Alle losse componenten nu verzameld in de FLOW. De FLOW eenvoudig gestart worden waarmee alle ETL's achterelkaar uitgevoerd worden. De flow kan vervolgens in de scheduler opgenomen worden om vervolgens iedere dag om 5 uur uitgevoerd te worden.

record_on('| FLOW PF_84466NED |')
    actualize_t2('| SOURCE DIM_TYPEZELFSTANDIGE_V | TARGET DIM_TYPEZELFSTANDIGE | MERGE_KEYS TYPEZELFSTANDIGE | ') 
    actualize_t2('| SOURCE DIM_GESLACHT_V         | TARGET  DIM_GESLACHT        | MERGE_KEYS GESLACHT | ') 
    actualize_t2('| SOURCE DIM_KENMERKEN_V        | TARGET  DIM_KENMERKEN       | MERGE_KEYS KENMERKEN | ') 
    actualize_t2('| SOURCE DIM_PERIODEN_V         | TARGET  DIM_PERIODEN        | MERGE_KEYS  PERIODEN | ') 
    actualize_t2('| SOURCE DIM_INKOMEN_V          | TARGET DIM_INKOMEN          | MERGE_KEYS  INKOMEN | ') 
    actualize_t2('| SOURCE FACT_84466NED_V        | TARGET FACT_84466NED        | MERGE_KEYS DIM_TYPEZELFSTANDIGE_id,DIM_GESLACHT_id,DIM_KENMERKEN_id,DIM_PERIODEN_id,DIM_INKOMEN_id | ') 
record_off()

flow_run('| FLOW PF_84466NED  | ')

STAP 6 : de scheduler

Wanneer we het datawarehouse per dag willen verversen kan dat middels de scheduler geregeld worden. We kunnen als frequentie 'DAY' gebruiken maar in ons voorbeeld gebruiken we ook SECONDS, om niet te lang te hoeven wachten. Wanneer je scheduler_start ( WAIT | ITERATIE ) aanroept, zet de een oneindige lus op, met een frequentie van wait - seconds. Indien je geen ITERATIE meegeeft, dan is de lus oneindig, en anders eindigt de lus na X- ITERATIES. Middels CALL en BCALL kan de scheduler aangeroepen worden. Met BCALL wordt de scheduler parrallel opgestart.

CALL PF_SCHEDULER_84466NED    -- 
of 
BCALL PF_SCHEDULER_84466NED   -- parrallel 

BEGIN PF_SCHEDULER_84466NED
 SET CONN SS_boss
 DISP de scheduler wordt gestart, tijdstip van starten: <NOW>. 
    schedule_add ("| FREQ DAY     |  TIME  5:00  | COMMAND   flow_run('| FLOW PF_84466NED |  ') ")
    schedule_add ("| FREQ SECONDS |  VALUE 1     | COMMAND   flow_run('| FLOW PF_84466NED |  ') ")
    schedule_start( '| WAIT 2 | ITERATIE 4 |' )
 DISP de scheduler is gestopped, tijdstip van stoppen: <NOW>. 
RETURN