Daten "Normalisierung" aus verschiedenen Quellen

OnDemand

Top Contributor
Hallo zusammen,

ich überlege grad ob es noch einfachere Möglichkeiten für folgendes gibt:

Für ein Projekt hole ich aus 13 Quellen Daten, diese Daten müssen im System zwischengespeichert werden um dann für andere Systeme verfügbar gemacht zu werden. Dabei ist jede Datenquelle komplett anders aufgebaut.

Man kann sich das so vorstellen als hätte man ein ERP System. In dieses ERP System holen wir Produktdaten von sämtlichen Herstellern (jeder Hersteller hat dabei eine andere API was Aufbau & Co angeht).

Nun haben wir es so geplant, dass wir eine nennen wir es "normalisierte" Form eines ERP-Entity erstellen und alle anderen Daten darauf passend machen und speichern.

Hier mal eine sehr vereinfachte Form (Dummycode)

Java:
class ErpEntity {
    String name;
    String beschreibung;
    Double preis;
    //und noch viele viele mehr
}

Java:
class ObjectFromManufacturerA{
    String title;
    String purchasePrice;
    //und noch viele mehr
}

Nun bauen wir aus dem ManufacturerObjekt ein ERP-Objekt und speichern es ab. Dann haben wir in unserem System eine einheitliche Datenstruktur welches wir an weitere Systeme weiterleiten können.

Java:
class Mapper {
    
    mapIt(ObjectFromManufacturerA objectFromManufacturerA){
        ErpEntity ee = new ErpEntity();
        ee.setPrice (objectFromManufacturerA.getPurchasePrice());
        ee.set ....

save(ee);
    }
    
}

Hat jemand noch ne bessere Idee wie man aus Objekt A ein ErpEntity bekommt? Das doofe ist halt, dass jeder Hersteller eine komplett andere Datenstruktur hat und da alles manuell angefasst werden muss um das zum ErpEntity zu bekommen
 

Robert Zenz

Top Contributor
Nein, wird nicht besser. Du kannst anfangen dir einen Helfer mit Reflection und Annotations zu schreiben, aber das macht die Sache alles nicht besser. In einem Projekt hatten wir auch einen generischen Mapper welcher Feldangaben aus einer Konfigurationsdatei verwendete um diese direkt zu mappen mit Hilfe von Reflection, hat die Sache auch nicht leichter zu warten gemacht meiner Meinung nach.

Ueberlege dir ob vielleicht die Konvertierungsmethode direkt in "ObjectFromManufacturerA" Sinn macht, anstelle einer eigenen Klasse, also eine "toErpObject" Methode dort. Da diese Klassen nur den Zweck haben ein "Zwischenschritt" auf dem Weg zu sein, wuerde es Sinn machen dort direkt die Methode zu haben anstelle sich noch eine Schicht aufzureissen, insbesondere dann wenn es immer nur einen Weg geben kann um diese Klassen zu konvertieren. Eventuell macht es auch schon Sinn einen Schritt frueher anzusetzen, so dass du schon nicht die spezifischen Klassen hast, sondern nur ErpEntitys rauswirfst aus den Klassen welche die Daten liefern. Also dass der eine Zwischenschritt ueber diese Klasse weggelassen wird (haette auch den Vorteil dass weniger Garbage anfaellt). Kommt natuerlich auf die Schnittstelle an der Stelle an. Damit koenntest du naemlich auch relativ simpel deine Datenlieferanten auf ein Interface reduzieren, und diese kovnertieren intern die Daten und reichen sie dann nach auszen als ErpEntity. Halbwegs sauber strukturiert kannst du da dann auch ganz einfach Unittests fuer die Konvertierung schreiben.
 

mrBrown

Super-Moderator
Mitarbeiter
Man kann sich das "manuelle Mapping" etwas vereinfachen, wenn man sowas wie Mapstruct oder Dozer nutzt, mit letzterem kann man die Mapping-Konfiguration dann auch wenn nötig in Konfigurations-Dateien auslagern.


Wie @Robert Zenz schon sagte sollte man die Sichtbarkeit des ganzen aber möglichst beschränken. Das eigentliche System kennt also nur die ErpEntity, und das Abfragen der Daten und das Mappen zu ErpEntity ist gekapselt in einem eigenem Package/Modul.
 

Meniskusschaden

Top Contributor
Hat jemand noch ne bessere Idee wie man aus Objekt A ein ErpEntity bekommt? Das doofe ist halt, dass jeder Hersteller eine komplett andere Datenstruktur hat und da alles manuell angefasst werden muss um das zum ErpEntity zu bekommen
Ich weiß nicht, ob es wirklich besser ist, aber für den gesamten Weg von den Hersteller-APIs bis in das eigene ERP-System würde ich komplett auf Programmierung verzichten und einfach ein ETL-Tool verwenden. Das Mapping der Hersteller-Informationen auf die eigene Datenstruktur kann doch bestimmt recht vielfältig werden und beschränkt sich vermutlich nicht nur auf einfache "Quellfeld-A nach Zielfeld-B"-Zuordnungen, sondern könnte auch komplexere Transformationen erfordern. Da hätte ich gerne die Macht eines solchen Tools zur Verfügung.
Damit würde ich die im ERP-System benötigten und direkt vorgesehenen Felder befüllen und alles wofür es im ERP keine Felder gibt, würde ich in Form von Sachmerkmalen bzw. Key-Value-Paaren als Zusatzinformationen bereit stellen. Dann hat man eben je eine hersteller-spezifische ETL-Transformation aber keine Hersteller-Spezifika in Anwendungscode oder Datenbank.
 

OnDemand

Top Contributor
Genau, ist nicht nur von A nach B sondern bedarf noch einiger Anpassungen. Zum Beispiel liefert ein Hersteller Bruttopreise, die müssen in netto gewandelt werden. Andere liefern keine sauberen EAN Nummern da müssen wir über ein wiederum anderes Tool erst passende ran holen usw :(
 

mihe7

Top Contributor
Hat jemand noch ne bessere Idee wie man aus Objekt A ein ErpEntity bekommt? Das doofe ist halt, dass jeder Hersteller eine komplett andere Datenstruktur hat und da alles manuell angefasst werden muss um das zum ErpEntity zu bekommen
Was ich manchmal bei solchen Dingen mache: erstmal in eine DB importieren und dann per SQL arbeiten, um mch dem gewünschten Ergebnis anzunähern, z. B. in Form einer View. Dann muss ich mich um lästige Dinge nicht im Programm kümmern :)
 

Dukel

Top Contributor
Genau, ist nicht nur von A nach B sondern bedarf noch einiger Anpassungen. Zum Beispiel liefert ein Hersteller Bruttopreise, die müssen in netto gewandelt werden. Andere liefern keine sauberen EAN Nummern da müssen wir über ein wiederum anderes Tool erst passende ran holen usw :(
Genau das machen ETL Tools auch. Das T steht dabei für _transform_.
 

OnDemand

Top Contributor
Was ist ein ETL Tool oO noch nie gehört. Was Wikipedia schreibt liest sich ja genau nach dem, was ich brauche
Extraktionder relevanten Daten aus verschiedenen QuellenTransformationder Daten in das Schema und Format der ZieldatenbankLadender Daten in die Zieldatenbank

So wie ich das verstehe ich das ein externes Tool, welchem ich sage wie die Daten aufgebaut sind und es das in meine DB schiebt?! Ist ja quasi das selbe wie ich es mache in meinen Beispielklassen oben. Hatte auch schon die Idee, eine Art template für jede Quelle anzulegen in welcher Steht in der Spalte A steht der Preis, Spalte B der Name usw. Wird dann aber schnell sehr komplex, wenn es Artikel gibt welche Eigenschaften haben (kennt man zb beim shoppen wenn es eine Hose in verschiedenen Größen gibt, mit einem Dropdown)

Hat jemand zufällig ein Beispiel? Hab mir grad Penthao angesehen, versteh ich spontan erstmal nicht :D
 
Zuletzt bearbeitet:

OnDemand

Top Contributor
Danke, hab mir mal Penthao installiert, ok Prinzip kapiert. Aber das ist ja eine Standalone App.
Ich brauch die Funktion quasi in meinem Programm. In deinem Link springt mich sofort spring Batch an. Ich nutze Spring Boot. Das schau ich mir direkt ma an
 

OnDemand

Top Contributor
Dann müsste man es pro Kunden nochmal konfigurieren.
Angenommen User A meiner Software will, dass das Programm Daten von Hersteller A holt.
Der User A hat bei Hersteller A aber andere Logindaten, als User B um an die Daten zu kommen.
 

Meniskusschaden

Top Contributor
Dann müsste man es pro Kunden nochmal konfigurieren.
Angenommen User A meiner Software will, dass das Programm Daten von Hersteller A holt.
Der User A hat bei Hersteller A aber andere Logindaten, als User B um an die Daten zu kommen.
Bedeutet das, du bekommst abhängig vom Kunden bei demselben Hersteller zwar gleich strukturierte Daten aber jeweils unterschiedliche Inhalte? Dann müsstest du die Zugangsdaten ja schon irgendwo in deiner DB haben. Die sollte sich das ETL-Tool ja von dort holen können, um dieselbe Transformation mehrmals mit unterschiedlichen Parametern aufzurufen. Dann müsste eine Konfiguration pro Hersteller ausreichen.

Ich würde mir die Transformation auch als getrennten Prozess vorstellen, so wie @temi es vorgeschlagen hat. Dadurch hat man aber natürlich eine Pufferung. Wenn die nicht akzeptabel ist, sondern die Kunden über eure Software in Echtzeit auf die Herstellerinformationen zugreifen müssen, wird es mit dem Ansatz schwierig.
 

OnDemand

Top Contributor
Ja stimmt, die Zugangsdaten haben wir abgespichert, da könnte das ETL Tool ran kommen. In Echtzeit greift keiner zu. Geht eher darum immer aktuelle Daten bei uns in der DB zu haben. Hab leider kein tool gefunden welches auch im Browser läuft (da unsere VMs keine GUI haben, sind reine Debianserver - da wird es schwierig).
 

Meniskusschaden

Top Contributor
Hab leider kein tool gefunden welches auch im Browser läuft
Ich weiß nicht, ob es das gibt, aber ich sehe auch die Notwendigkeit nicht. Normalerweise sollte die Konfiguration zentral in irgendeiner Form von Repository liegen, z.B. als eigene Datenbank. Die Pflege erfolgt remote über eine Clientsoftware. Für die Ausführung der Transformationen sollte keine GUI erforderlich sein.
 

OnDemand

Top Contributor
Ahha verstehe. Welches ETL Tool wäre denn am einfachsten zu nutzen? Der Prozess sollte dann als Service auf dem Debian laufen, richtig?
In Penthao Kettle kann man sein "Template" exportieren, das sollte dann von allesn Clients benutzt werden um Hersteller A zu importieren. Wenn man das Template updated, kann man das sicherlich irgendwie an die Clients verteilen. Das klingt erstmal hervorragend, aber die Umsetzung uiuiui sieht sehr komplex aus so ein ETL Tool
 
Zuletzt bearbeitet:

OnDemand

Top Contributor
Könnte man mit dem ETL auch folgendes umsetzen: Wenn Produkt XY schon existiert, nur den Namen updaten oder nur den Preis usw? Dann müsste das ETL erstmal wissen ob das Produkt schon existiert.
 

Meniskusschaden

Top Contributor
Welches ETL Tool wäre denn am einfachsten zu nutzen?
Ich habe da leider keinen Marktüberblick. Uns genügt die Community-Edition von Pentaho Data Integration (PDI), also die ETL-Komponente der Pentaho Suite.
Der Prozess sollte dann als Service auf dem Debian laufen, richtig?
Wir starten dazu einfach auf unserem "Integrationsserver" zeitgesteuert per Job-Scheduler die CLI-Befehle von PDI (pan bzw. kitchen). Also ziemlich banal. Dort liegt auch das Repository. In eurem Fall wäre das wohl der Debian-Server. Prinzipiell könnte man das bestimmt auch gut auf mehrere Server verteilen, falls man Lastprobleme hat.
In Penthao Kettle kann man sein "Template" exportieren, das sollte dann von allesn Clients benutzt werden um Hersteller A zu importieren. Wenn man das Template updated, kann man das sicherlich irgendwie an die Clients verteilen.
Ich bin nicht sicher, was du hier mit den Clients meinst. Das Konfigurationstool? Zur Definition der Transformationen benutzen wir das GUI-Tool von PDI (spoon). Das kann man prinzipiell von jedem Desktop aus starten, benötigt aber Zugriff auf das Repository (bei uns auf dem Integrationsserver). Wir arbeiten dann auch direkt auf dem Repository und exportieren da nichts mehr. Bei höheren Qualitätssicherungsanforderungen würde man sich vermutlich noch ein Test-Repository anlegen und müsste seine Transformationen dann irgendwie in die Produktionsumgebung übertragen. Vielleicht funktioniert es auch, statt eines DB-Repositories ein Dateisystem-basiertes Repository zu verwenden und unter Versionskontrolle zu stellen. Das habe ich aber noch nie ausprobiert.
Könnte man mit dem ETL auch folgendes umsetzen: Wenn Produkt XY schon existiert, nur den Namen updaten oder nur den Preis usw? Dann müsste das ETL erstmal wissen ob das Produkt schon existiert.
So eine Transformation kann natürlich beliebig komplex werden. Im einfachsten Fall würde hier wohl ein einfacher Insert-/Update-Schritt am Ende der Transformation ausreichen. Hier ist mal ein einfaches Beispiel. Falls der EAN-Code noch nicht im ERP existiert, wird er mit Name und Preis erstellt, andernfalls erfolgt ein Update auf den Preis, aber nicht auf den Namen.Bildschirmfoto vom 2021-03-14 17-00-00.png
 

OnDemand

Top Contributor
Das klingt zu gut um wahr zu sein!

Manche Hersteller liefern Bilder per Link, diese müssen wir herunterladen. Ginge das?

Könnte man auch folgendes abbilden:
Wir haben eine CSV Datei. Es gibt Artikel die gibt es in verschiedenen Größen. Jede Zeile ist dabei eine Variante. Das ist natürlich wieder bei jedem Hersteller anders.

Ein Beispiel

SKU; VATER; NAME; Farbe
123; AAA; Herrenhose; rot
456; AAA; Herrenhose; blau

Das ist quasi eine Herrenhose mit der Haupt-SKU AAA welche es in 2 Farben gibt.

Unser Objekt sieht in etwa so aus:

[CODE lang="java" title="Product.java"]class Product (){
String mainSku;
List<Combinations> combinations;
}

class Combinations (){
String sku;
String farbe;
} [/CODE]
 

OnDemand

Top Contributor
Hab mir mal einen Udemy Kurs gekauft, wenn das funktioniert wie ich mir das vorstelle wäre das genial!

Ziel ist es eine zentrale zu haben, wo die "templates" von uns vorgefertigt liegen auf welches alle Clients zugreifen können. Sodass wir die nur an einer Stelle bearbeiten müssen falls sich was ändert
 

Meniskusschaden

Top Contributor
Manche Hersteller liefern Bilder per Link, diese müssen wir herunterladen. Ginge das?
Ja, das sollte funktionieren. Für den Anwendungsfall würde man sich einen http(s)-Download in der Transformation wünschen. PDI bietet das derzeit zwar nur im Job an, aber man kann Jobs aus Transformationen heraus aufrufen (der Normalfall ist anders herum), so dass das keine Einschränkung ist (eigentlich sind Jobs eher dazu gedacht, den ETL-Prozess zu koordinieren und die Transformationen machen die Arbeit).
Könnte man auch folgendes abbilden:
Wir haben eine CSV Datei. Es gibt Artikel die gibt es in verschiedenen Größen. Jede Zeile ist dabei eine Variante. Das ist natürlich wieder bei jedem Hersteller anders.
Das sieht auch nicht so schwierig aus. Allerdings sind aus ETL-Sicht eher die DB-Tabellen interessant, nicht so sehr die Java-Ḱlassen.
 

Ähnliche Java Themen

Neue Themen


Oben