Im dritten Teil unserer XSA-Blogreihe gehen wir im Detail auf den Prozess des Datenladens ein. Wie werden Daten aus einem Quellsystem geladen? Wie werden Daten innerhalb eines HDI Containers von einer Tabelle in die andere geladen? Welche Artefakte gibt es? Alle relevanten Fragen werden mithilfe unseres Beispielprojekts beantwortet und veranschaulicht.
Grundlagen der Datenbeladung
Mit unserem ersten Blog haben wir die Grundlagen für XSA erklärt, durch den zweiten Blog haben wir die persistenten Strukturen verstanden und unser XSA Beispielprojekt angelegt. Auch bei dem Thema Datenladen gilt, dass die XSA Umgebung neue Wege geht und eigene Services und Strukturen verwendet.
Jede Datenbank benötigt Daten. Besonders bei Data Warehouse Systemen nimmt das Datenladen eine zentrale Rolle ein, da die Daten von verschiedensten Quellsystemen angebunden und harmonisiert werden. Für die Bewältigung der Aufgabe bietet SAP diverse Artefakte an, die in der folgenden Abbildung zusammengefasst sind.
Abbildung 1 – Artefakte zum Datenladen
Replikation Tasks (.hdbreptask) sind in der Lage, Daten aus Quellsystemen über virtuelle Tabellen zu laden, wobei auch Realtime, Delta und einfache Transformationen möglich sind. Auch das Laden von DataSources aus z.B. einem S/4HANA System ist möglich.
Flowgraphs (.hdbflowgraph) werden im Standard für das Laden zwischen persistenten Tabellen verwendet. Über die graphische Oberfläche kann mithilfe von Standardknoten wie Projektionen, Joins oder Table Comparisons die entsprechende Funktionalität leicht realisiert werden.
Prozeduren (.hdbprocedure) stellen die Expertenlösung dar, da mithilfe von SQLScript alle Möglichkeiten der Datenbeladung und Manipulation vorhanden sind. Auf die Prozeduren werden wir in diesem Blog nicht weiter eingehen, da diese immer speziell nach dem Anwendungsfall gebaut werden und oft spezifische Logik enthalten. Daher konzentrieren wir uns auf die Standardobjekte Replikation Task und Flowgraph.
Anbindung Quellsystem
In diesem Abschnitt möchten wir in unserem Beispielprojekt ein HANA Quellsystem anbinden. Leider lässt sich das nicht mit wenigen Klicks realisieren, sondern benötigt eine Reihe von Einstellungen und Aufgaben, wobei wesentliche Schritte außerhalb des BAS-Projekts vorgenommen werden müssen. Für unser Beispielprojekt verfolgen wir das folgende Ziel: Anbindung eines HANA Systems, Laden der CUSTOMERS-Tabellen und Beladung in unsere CUSTOMERS Tabelle aus dem XSA Projekt. Dabei wollen wir unsere CUSTOMER Tabelle so erweitern, dass Historisierungen möglich sind. Damit ergibt sich das folgende Zielbild.
Abbildung 2 – Übersicht Szenario
Leider müssen viele der Komponenten manuell aufgebaut und gewartet werden. Zunächst wird ein Data Provisioning Agent (DPA) benötigt. Dabei handelt es sich um eine separate Softwarekomponente von SAP, die allgemein für den Datenaustausch zwischen Systemen zuständig ist. Die Einrichtung des DPA würde diesen Blog sprengen, sodass wir nur zusammenfassend folgende Schritte angeben:
- Lokale Installation des DPA
- Starten des Dienstes (Windows)
- Verbindung des DPA mit der HANA Cloud Instanz
- Registrierung eines Agenten
- Installation des Adapters „HanaAdapter“
Nun kann das HANA System als neues Quellsystem im Database Explorer angelegt werden. Dies kann z.B. mit dem DBADMIN-User gemacht werden.
Abbildung 3 – Hinzufügen Remote Source
In unserem Beispiel verbinden wir unsere HANA Cloud Instanz mit sich selbst, sodass wir das Quellsystem MYSELF nennen und unter der Verwendung des Adapters „HanaAdapter“ den eigenen Host angeben. Wenn alles korrekt eingerichtet ist, werden unter der neuen Remote Source die entsprechenden Objekte angezeigt.
Abbildung 4 – MYSELF
Das nächste Ziel besteht darin, eine Tabelle aus dem System anzubinden. Dafür legen wir eine lokale Datenbanktabelle im vorher erstellten Schema SFLIGHT an. In diese Tabelle fügen wir zwei Test-Datensätze ein. Das simuliert unsere Quelltabelle im Quellsystem.
Abbildung 5 – Quelltabelle
XSA Projekte leben in ihren eigenen HDI Containern und die User innerhalb eines HDI Containers haben nur beschränkte Rechte. Damit unser HDI User die Berechtigungen auf die neue Remote Source bekommt, benötigen wir eine technische Rolle und einen User, der zentral für die Anpassung der Remote Source zuständig ist. Die folgenden SQL Statements erledigen diese Aufgabe. Somit ist der User GRANTOR_SERVICE berechtigt, eine virtuelle Tabelle auf der Remote Source anzulegen.
Abbildung 6 – Einrichtung Grantor Service
Als nächstes wird ein User Provided Service (UPS) benötigt. Mit diesem Service können die Berechtigungen des Users zentral gespeichert und bei Bedarf ausgetauscht werden. Zusätzlich könnte in einem UPS die gesamte Datenbankverbindung hinterlegt sein, sodass ein Switch auf ein anderes System über nur einen Service gesteuert werden kann. Der UPS wird direkt im BTP unter dem entsprechenden Space unter „Instances“ angelegt.
Abbildung 7 – Erstellung UPS
Nun gilt es diesen Service in unserem XSA Projekt zu hinterlegen. Dafür wird zunächst die zentrale Steuerungsdatei unseres Projekts (mta.yaml) um die entsprechende Ressource erweitert. Zusätzlich wird das db-Modul um die entsprechende Abhängigkeit erweitert.
Abbildung 8 – Erweiterung mta.yaml
Als nächstes erstellen wir den Ordner „cfg“ direkt unter dem db-Ordner. Der Name „cfg“ ist dabei zwingend so zu verwenden, da die Dateien aus diesem Ordner zuerst deployed werden, weswegen Berechtigungen auf das Quellsystem dort abgelegt werden. In dem neuen Ordner legen wir die Datei „myself.hdbgrants“ mit folgendem Inhalt an.
Abbildung 9 – Grants
Diese Grants-Datei zieht über den angegebenen Service die nötigen Berechtigungen für die Remote Source. Es fehlt nur noch eine letzte Anpassung, bevor wir mit dem Datenladen beginnen können. Die Grants-Datei verweist auf „ServiceName_1“. Auch innerhalb eines XSA Projekts kann man zu Entwicklungszwecken (ähnlich zu einem UPS) Services nicht direkt ansprechen, sondern ein Mapping anlegen. Dieses Mapping wird in der .env-Datei hinterlegt.
Abbildung 10 – Anpassung .env (1/2)
Für die lokalen Entwicklungen im eigenen HDI-Container wird die .env-Datei verwendet, um die jeweiligen Verbindungsinformationen zu lesen. Beim Deployment der gesamten Applikation wird dann der UPS aus dem BTP ausgelesen.
In derselben .env-Datei muss noch unter „VCAP-SERVICES“ ein entsprechender Eintrag für den lokalen UPS hinzugefügt werden. Da diese neue Umgebungs-Datei nur schwer zu lesen ist, kann über den Termin-Befehl „hana-cli copy2DefaultEnv“ eine alte default-env.json erstellt werden.
Abbildung 11 – Anpassung .env (2/2)
Nach dem Hinzufügen des UPS kann diese Datei dann wieder mit „hana-cli copy2Env“ zu der .env umgewandelt werden.
Anlegen Replikation Task
Puh! Nach all dieser Arbeit ist es nun möglich auf das neue Quellsystem zuzugreifen. Damit können wir endlich einen Replikation Task anlegen. Im db-Ordner erstellen wir einen „reptask“ Ordner und dort einen neuen Replikation Task.
Grundlegend wird in einem Replikation Task ein Quellsystem angegeben und einzelne Objekte, die geladen werden sollen, werden gepflegt. Dabei sind mehrere Objekte eines Quellsystems in einem Replikation Task möglich. Ein Objekt benötigt immer eine virtuelle Tabelle und eine persistente Struktur, in der die Daten abgelegt werden sollen.
Dabei kann der Replikation Task diese Objekte direkt anlegen oder es werden über separate Artefakte die entsprechenden Tabellen angelegt. Zusätzlich können pro Objekt weitere Detaileigenschaften wie Partitionen, Filter oder Mappings definiert werden.
Abbildung 12 – Anlegen Replikation Task
Im Replikation Task selbst verbinden wir uns zunächst mit dem Quellsystem MYSELF. Anschließend können wir über das „+“-Zeichen neue Objekte anlegen. Im entsprechenden Menu entscheiden wir uns für die CUSTOMERS-Tabelle
Abbildung 13 – Auswahl Tabelle
Wir möchten, dass der Replikation Task die benötigte virtuelle Tabelle und Ziel-Tabelle anlegt. Dabei können wir entsprechende Präfixe der Tabellen definieren.
Abbildung 14 – Pflege Präfix
In den Mapping-Regeln legen wir eine neue Spalte „LOAD_DATE“ an, in welche das aktuelle Datum geschrieben werden soll.
Abbildung 15 – Mapping
Zusätzlich kann unter den Target Properties definiert werden mit welchen Einstellungen die Zieltabelle gefüllt werden soll. Dabei kann bestimmt werden, ob gelöschte Zeilen beachtet werden sollen und ob die neuen Datensätze über ein Insert, Update oder Upsert eingefügt werden sollen. Nun ist der Replikation Task bereit für das Deployment und kann danach direkt ausgeführt werden. Für das Monitoring des Tasks findet sich im Kontextmenu ein Task Monitor.
Abbildung 16 – Ausführung Replikation Task
Nach dem erfolgreichen Ausführen können wir sehen, dass die zwei Datensätze aus der angelegten CUSTOMERS-Tabelle erfolgreich geladen wurden.
Abbildung 17 – Test neue Datensätze
Anpassung Customer
In unserem Szenario möchten wir gerne unsere vorhandene Tabelle CUSTOMERS so abändern, dass die Information historisiert wird. Hier hilft uns wieder CAP und CDS mit vorgefertigten Aspekten. Wir können bequem den Aspekt „temporal“ zu unserer Tabelle hinzufügen.
Abbildung 18 – Hinzufügen Aspekt temporal
Durch diese Änderung werden automatisch „VALIDFROM“ und „VALIDTO“ Spalten eingefügt und der Schlüssel um „VALIDFROM“ erweitert. Damit unser Szenario mit den Test-Dateien weiter funktioniert, müssen auch die Testdaten um entsprechende Felder erweitert werden.
Abbildung 19 – Anpassung Test-Dateien
Anlegen Flowgraphen
Mit einem Flowgraphen kann das Laden innerhalb des HDI Containers realisiert werden. Wie gewohnt erstellen wir einen Ordner „flowgraphs“ unter „db“. Dort erstellen wir über den Wizard den Flowgraphen „FG_BT_CUSTOMERS“.
Flowgraphen bestehen immer aus mindestens einer Quelle und mindestens einem Ziel. Über vordefinierte Standardknoten können Aufgaben wie Projektionen, Filterungen, Joins, Tabellenvergleiche oder Historisierung einfach ausgeführt werden.
Abbildung 20 – Basis Knoten
Es sei aber erwähnt, dass die Funktion der Knoten teilweise eingeschränkt ist und diese nicht viel Flexibilität bieten. So können nicht beliebige Knoten miteinander verbunden werden. Hinter „Table Comparison“ Knoten kann z.B. kein Prozeduren-Knoten eingesetzt werden.
Daher kann es bei komplizierten Fällen erforderlich sein, Prozeduren zu schreiben und Abgleiche zwischen Tabellen und das Einfügen von Daten über SQL Befehle wie „MERGE“, „INSERT“ oder „UPDATE“ zu schreiben. Als Beispiel für einen Flowgraphen könnten z.B. zwei Tabellen (unsere Billing Header und Items) gejoint und in eine neue Tabelle geschrieben werden.
Abbildung 21 – Beispiel Flowgraph
In unserem konkreten Beispiel wollen wir aber aus unserer replizierten Tabelle TARGET_CUSTOMER in unsere historisierte Kunden-Tabelle schreiben. Insgesamt wird unser Flowgraph die folgende Form haben.
Abbildung 22 – Flowgraph Customer
Wie zu sehen ist, verwenden wir für den Abgleich der Daten und der Erstellung der Historie die Standardknoten. Diese sind in der Lage die entsprechenden Datensätze anhand der Schlüssel und Attribute zu vergleichen und die Historie aufzubauen, d.h. alte Datensätze werden abgeschlossen und neue Datensätze werden mit entsprechender Gültigkeit eingefügt.
Im TableComparison-Knoten wird intuitiv gepflegt, welche Tabellen verglichen werden und welche Attribute dafür verwendet werden. Leider ist aktuell der Vergleich von NCLOB-Spalten nicht möglich, sodass wir unsere E-Mail-Spalte nicht verwenden können. In dem HistoryPreserving-Knoten sind eine Reihe von Einstellungen möglich.
Abbildung 23 – Pflege Historisierung
Neben der Angabe der Zeitspalten „VALIDFROM“ und „VALIDTO“ kann pro Datensatz angegeben werden, wie diese gefüllt werden soll. Bei Bedarf kann auch ein weiteres Flag gesetzt werden, um den aktuellen Datensatz direkt zu identifizieren.
Führen wir den Flowgraphen nach dem Build aus, so werden zunächst die zwei Datensätze mit entsprechender Gültigkeit einfach eingefügt. Zur Ausführung kann entweder direkt die Funktion im BAS verwendet werden oder über das SQL-Statement „START TASK FG_BT_CUSTOMERS“.
Nun allerdings verändern wir in der Quelltabelle einen Datensatz über ein UPDATE-Statement. Wir ändern die Beschreibung eines Kunden von „Mathias Klare“ zu „Mathias Cube“.
Anschließend führen wir den Replikation Task und den Flowgraphen aus. Im Ziel finden wir nun das gewünschte Ergebnis wieder. Die Gültigkeit des vorhandenen Kunden wurde beendet und ein neuer Datensatz wurde eingefügt.
Abbildung 24 – Historisierter Datensatz
Es ist auch möglich Daten zwischen zwei HDI Containern zu laden. Allerdings werden auch hier wieder weitere Objekte benötigt, damit sich die isolierten HDI Container kennen. Wie genau diese Verbindung hergestellt werden kann, schauen wir uns im nächsten Blog genauer an.
Fazit
Die vielen Schritte für das Anlegen eines Quellsystems haben es gezeigt: Der Umgang mit der XSA ist an manchen Stellen wenig intuitiv und bedarf vieler Detail-Kenntnisse. Auf der anderen Seite wird mit den Artefakten wie Replikation Tasks und Flowgraphs ein eingängiger Standard für das Datenladen geboten.
Dennoch kann auch durch diesen Standard oft nicht jede Logik implementiert werden und es bleibt nur das direkte Coden mit SQLScript und Datenbankprozeduren. Ein weiteres Thema ist das Einplanen von Ladeprozessen. Diese sind nicht direkt im XSA Projekt möglich, sondern erfordern einen weiteren Service: den Job Scheduler. Dabei handelt es sich wieder um eine weitere Oberfläche innerhalb der BTP mit eigenen Befehlen und Berechtigungen.
Das Datenladen gehört damit zu dem komplexesten Thema im XSA Umfeld. Dieser Blog liefert dafür eine Übersicht der verschiedenen Möglichkeiten und grenzt die Objekte ab. Im nächsten Blog beschäftigen wir uns mit der virtuellen Modellierung und der Frage, wie die Daten für ein Reporting aufbereitet werden können.