Shopware Migration Assistant - Einfach, flexibel, erweiterbar
Um Shopbetreibern eine möglichst einfache und intuitive Datenmigration zu ermöglichen stellt Shopware den Migrationassistenten zur Verfügung. Dieser Assistent ermöglicht es dem Benutzer unkompliziert Daten aus anderen Systemen nach Shopware 6 zu übernehmen, bei Bedarf auch mehrfach. Durch die Funktion der mehrmaligen Migrationen muss die Shopware 6-Instanz nicht wieder zurückgesetzt werden, falls sich der Datenbestand auf dem Quellsystem ändert. Die Migrationsschnittstelle ist, wie alles in Shopware, gut erweiter- und anpassbar. So können Entwickler in Agenturen oder Pluginentwickler Funktionen ergänzen oder ändern, die für ihren spezifischen Anwendungsfall notwendig sind.
Konzept und aktuelle Profile
Die Migration besteht aus mehreren Teilen, die alle von zwei übergeordneten Komponenten abhängen: Profile und Gateways.
Profile definieren das Shopsystem, das die Quelle der Daten darstellt. Diese Profile sind wiederum in einzelne Gateways aufgeteilt. Die Gateways definieren wie die zu migrierenden Daten vom Quellsystem geholt werden. Als Beispiel, in den Shopware 5 Profilen kann die Migration auch über eine API stattfinden, die ein Plugin im Shopware 5 Quellsystem bereitstellt, der Shopware Migration Connector. Das Migration-Connector-Plugin stellt eigene, auf die Migration zugeschnittene API-Routen bereit, um die Migration performanter und flexibler zu gestalten. Der Migration Connector wurde so konstruiert, dass auch andere Plugins diesen Weg einfach erweitern können.
Ein Gateway das in allen Profilen von Shopware vorhanden ist, ist das Local-Gatway. Es ermöglich die Migration von Daten aus einer lokalen Datenbank. Die aktuell vorhandenen vorgefertigten Shopware 5 Profile umfassen die Versionen ab Shopware 5.4, für jede Minor-Version ein Profil. Für die Migration von Daten aus Magento 1 gibt es zur Zeit das Profil für die Version 1.9, die Kompatibilität mit niedrigeren Minor-Versionen ist noch in der Prüfung. Bei Magento 2 existieren Profile für die Versionen ab 2.0 bis 2.3.
Der generelle Ablauf bei der Migration über den Shopware Migration-Assistent fängt mit der Erstellung einer Verbindung an. Hierzu wählt man einen passenden Verbindungsnamen, definiert, welches Profil und welches Gateway genutzt werden soll. Im nächsten Schritt müssen die Zugangsdaten zum Gateway eingeben werden, danach wird ein Verbindungstest durchgeführt. Ist der Verbindungstest erfolgreich, stehen die Daten nun zur Migration bereit. Die Daten werden zu mehreren Datenauswahlen (sogenannten DataSelections) gebündelt, da manche der Daten Abhängigkeiten untereinander aufweisen und somit eine einzelne Migration nicht sinnig oder unmöglich ist. Nachdem eine oder mehere Datenauswahlen selektiert sind, kann die Migration gestartet werden. Sie beginnt mit einem kleinen Datencheck, auch Premapping genannt. In diesem Premapping muss der Benutzer eine manuelle Zuordnung von Datensätzen vornehmen, die Shopware 6 nicht autmatisch durchführen kann. Ein gutes Beispiel hierfür ist der Bestellstatus. Die verfügbaren Status unterscheiden sich in der Regel zwischen Quellsystem und Shopware 6 und müssen manuell zugeordnet werden. Nachdem alle Einträge des Premappings ausgefüllt wurden, kann der eigentliche Migrationsprozess starten.
Im ersten Schritt der Migration werden die Daten über das Gateway vom Quellsystem abgerufen und über sogenannte Converter in das entsprechende Shopware 6 Format konvertiert. Nachdem das Importieren der Daten abgeschlossen ist, werden die von den Konvertern aufbereiteten Daten über die Writer als neue Shopware 6 Entität gespeichert. Falls auch Medien migriert werden sollen, wird als nächster Schritt der Mediendownload bzw. das Kopieren der Medien angestoßen, sodass dieser aufgrund der Datenmengen langlaufende Prozess im Hintergrund durchgeführt wird. Zum Schluss der Migration wird die Indexierung der geschriebenen Daten im Hintergrund durchgeführt, sodass alle Entitäten durchsuchbar sind. Falls Fehler, Warnungen oder Informationen innerhalb der Migration auftreten, werden diese abgespeichert und können in der Verlaufsübersicht der Migration eingesehen werden.
Komponenten der Migration
Im Folgendem werden die wichtigsten Bestandteile der Migration dargestellt sowie der generelle Aufbau der Implementierung. Profile dienen lediglich zur Unterscheidung bzw. Identifizierung welche Unterkomponenten, wie zum Beispiel Converter, aufgerufen werden sollen. Somit enhalten Profile keine Logik, sondern ausschliesslich Funktionen zur Rückgabe von Informationen wie Name oder Version, die dann in der Administration* ausgegeben werden.
__*__Die Administration ist das Frontend der Verwaltungsoberfläche von Shopware 6. Der frühere Name "Backend" wird nicht mehr verwendet, da diese Bezeichnung korrekterweise auf auf die nicht-sichtbare Logik der Applikation (e.g. PHP) abzielt.
Gateways dienen zur Kommunikation zwischen Shopware 6 und dem Quellsystem und beinhalten somit alles, was zum Verbindungsaufbau und der Datenabfrage benötigt wird.
Das Gateway nutzt Reader, um Daten abzufragen. Die Reader werden über die Registry identifiziert und dann aufgerufen. Ein LocalReader zum Beispiel führt SQL-Abfragen über die Datenbankverbindung aus, sammelt die zurückgegebenen Daten und stellt sie dem Gateway bereit. Die Reader werden per support-Funktion von der Registry ausgewählt, hierbei wird das Profil, das Gateway und die gerade zu lesende Entität berücksichtigt. Das eigentlich Abrufen der Daten passiert dann in der fetchData-Methode, die je nach Entität* sehr komplex sein kann.
__*__Objekte, die im Rahmen der Datenmodellierung eindeutig bestimmbar sind und zu denen Informationen gespeichert und geladen werden können. Häufig genutzt im Sinne von "bedeutungstragende Datentypen im System". Beispiele für Entitäten sind demnach vor allem Produkte, Einkaufswelten, Kunden, Bestellungen, Hersteller etc. Rein technisch können aber auch Länder, Sprachen, Währungen, etc. darunter fallen.
Um die Datenauswahl in der Administration von Shopware 6 zu füllen und um die Identifizierung der folgenden Komponenten zu ermöglichen, werden DataSelections genutzt. Da diese lediglich zur Darstellung und Identifizierung genutzt werden ist hier keinerlei Logik implementiert. Es wird lediglich ein Struct über die getData-Funktion zurückgegeben. Dieses Struct enthält unter anderem einen Identifier, alle Entitäten die migriert werden sollen sowie einen Snippet-Namen für die Darstellung in der Administration.
DataSelections enthalten mehrere Entitäten. Zur Steuerung der Granularität gibt es die DataSets. Sie identifizieren die Entitäten für die Migration, so dass weitere Komponenten, wie zum Beispiel Converter, nur eine Entität verarbeiten müssen.
Für manche Entitäten ist es notwendig, neben dem Reader für das Gateway einen weiteren Reader zu erstellen, den PremappingReader. Er stellt eine passende Auswahl von Quell- und Zielmöglichkeiten zur Verfügung, dadurch erhält der Benutzer beim Starten der Migration eine Übersicht über alle noch erforderlichen manuellen Zuweisungen. Der PremappingReader ist von dem Profil und der Datenauswahl abhängig und muss somit eine support-Funktion implementieren. In der getPremapping-Funktion werden die Quelldaten und die Zieldaten für das Premapping ausgelesen und danach zurückgegeben. Falls eine Vorauswahl möglich ist, oder eine Auswahl schon aus einer vorherigen Migration besteht, kann diese Vorbelegung auch hier realisiert werden.
Die gelesenen Daten werden dann vom Gateway wiedergegeben und von dem entsprechenden Service zu dem zugehörigenden Converter weitergeleitet. Der Converter beinhaltet die eigentliche Logik der Migration und wandelt die eingehenden Daten in die Shopware 6 Struktur um. Auch der Converter nutzt eine support-Funktion zur Identifizierung des richtigen Profils und der entsprechenden Entität. Über die convert-Funktion erhält der Converter die Originaldaten, wandelt diese in eine Shopware 6 Struktur um und gibt sie zurück, sodass die umgewandelte Struktur in der Datenbank zwischengespeichert werden kann.
Nachdem die Shopware 6 Struktur erzeugt wurde, werden daraus die eigentlichen Shopware 6 Entitäten. Dies passiert durch die Writer. Writer beinhalten zur Identifizierung eine ensprechende support-Funktion, wodurch die korrekte Entität geschrieben wird. In der writeData-Funktion werden wenn notwendig noch kleine Anpassungen oder Kalkulationen durchgeführt, aber meist wird nur noch der EntityWriter aus dem Core genutzt, um die Entität zu erstellen. Wie im Codebeispiel zu sehen, wird hier die upsert-Funktion genutzt, die einen neuen Datensatz erstellt oder einen schon vorhandenen Datensatz aktualisiert, wodurch auch eine mehrfache Duchführung der Migration möglich ist.
Die letzte Komponente ist der MediaProcessor, der je nach Profil und Gateway unterschiedlich implementiert werden muss. Zum Beispiel muss bei der Migration über die API* ein Download der Medien erfolgen und bei einer Migration aus einer lokalen Datenbank, bei der auch die Medien lokal vorhanden sind, müssen diese Datein im Dateisystem des Servers kopiert werden. Daher liefert der MediaProcessor eine support-Funktion mit, die den Processor identifiziert. Die eigentliche Logik der Medien-Migration wird in der process-Funktion implementiert.
__*__Beschreibt die API selbst aber auch das Naming der ehemalige Core API
Erweiterungsmöglichkeiten
Der Migration-Assistent ist als einfach und stark erweiterbares System konzipiert. Dafür wurde zum Beispiel für die Migration von Magento eine einheitliche Converter-Basis pro Entität basierend auf dem Stand von Magento 1.9 entwickelt. Jeder Converter, der von dieser Basis abweicht, kann von dem Basis-Converter ableiten und die entsprechende Logik anpassen. So wurden auch die Converter der Magento 2 Migration realisiert, da vieles in Magento gleich blieb und nur kleinere Anpassungen nötig waren. Dies gilt ebenso für die Reader der Gateways und Premappings. Sie haben eine Basis-Logik, von der immer abgeleitet werden kann. Falls eine von einer Minor-Version abhängige Anpassung realisiert werden muss, wurden für jede Minor-Version auch einzelne Converter bereitgestellt, damit ein manueller Versionswechsel nicht notwendig ist. Wenn die Logik eines Converters angepasst oder erweitert werden muss, wird dazu das Decorator-Pattern verwendet. Angenommen die Logik des Produkt-Converters von Shopware 5.5 soll angepasst werden, sodass die Hersteller per Premapping ausgewählt werden. Um das zu erreichen, muss der entsprechende Converter dekoriert und mit der eigenen Logik erweitert werden.
Mit der Verwendung des MappingService kann dann der ausgewählte Wert aus dem Premapping abgefragt und zu den zu konvertierenden Daten hinzugefügt werden. Bei Plugins mit eigenen Tabellen hilft es nicht, einen bestehenden Converter anzupassen, da dessen Entität und Daten nicht mit abgefragt würden. Für solche Fälle kann der Migration-Assistent mit einer eigenen Datenauswahl erweitert werden, wodurch die Daten bei der Migration mit beachtet werden. Eines unser bekannten Beispiel-Plugins SwagBundle umfasst eine eigene Tabelle und könnte die Migration erweitern, um die eigenen Daten mit zu migrieren. Dafür müsste im ersten Schritt ein eigenes DataSet erstellt werden, dann können alle weiteren Komponenten mit dieser Entität arbeiten.
Im nächsten Schritt würde dieses DataSet zu einer DataSelection hinzugefügt werden, dadurch wird diese Entität auch bei der Migration abgefragt. Dafür kann eine eigene DataSelection erstellt oder eine vorhandene dekoriert werden.
Wenn ein DataSet in einer der DataSelections enhalten ist, wird es bei der Migration beachtet und es wird versucht, über das Gateway einen passenden Reader aufzurufen. Dieser Reader muss die Daten aus der Tabelle lesen, gegebenenfalls in eine passende Struktur bringen oder mit weiteren Daten anreichern und diese dann zurückgeben.
Nach dem Lesen der Daten folgt das Herzstück der Migration: Das Konvertieren. Ein Converter erhält dazu die vom Reader abgefragten Daten und wandelt sie in die neue Datenstruktur um.
Als letzter Schritt erfolgt das Schreiben der konvertierten Daten durch einen passenden Writer. Da der vordefinierter AbstractWriter die Standard-Logik beinhaltet, ist die Definition eigener Writer sehr schlank.
Mit dem eben beschriebenen Beispiel würden die Daten der Bundles mitsamt der Relationen zu den Produkten migriert werden. Wie man sieht, lassen sich so mit ein paar Handgriffen die alten Plugindaten zu Shopware 6 migrieren. Aber was ist zu tun, wenn keines der vorhandenen Profile zu dem Quellsystem passt? Wenn zum Beispiel eine ältere Magento-Version oder Shopware-Version oder sogar ein ganz anderes Shopsystem als Quellsystem vorhanden ist und dafür kein Profil vorhanden ist, muss ein eigenes Profil geschrieben werden. Der Migration-Assistant ist dafür bereits ausgelegt, es ist also nicht notwendig, eine ganz eigene Implementation zu realisieren. Ein gutes Beispiel hierfür sind die Magento-Profile. Alle Magento-Profile wurden separat als ein eigenes Magento-Plugin implementiert und nutzen die vorgefertigte Migrationslogik des Migration-Assistent. Um ein eigenes Profil bereitzustellen, wird im ersten Schritt eine eigene Profil-Klasse benötigt. Dies umfasst keinerlei Logik, nur ein paar Eigenschaften mit dazugehörigen Gettern.
Als nächstes wird ein eigenes Gateway benötigt, was zum Beispiel wie das lokale Datenbank-Gateway des Shopware-Profils implementiert werden kann, sodass der Zugriff auf die Datenbank durchgeführt wird. Natürlich können in dem eigenen Gateway auch noch andere Kommunikationswege (z. B. REST-API, SOAP-API etc.) genutzt werden, sofern das Quellsystem sie bereitstellt. In der support-Funktion des Gateways muss auf das eigene Profil überprüft werden, damit das eigene Gateway auch von der Migration genutzt wird.
Als nächstes müssen alle zu migrierenden Entitäten des Quellsystem überprüft und die und die Migrationskomponenten dafür erstellt werden. Wie schon oben erläutert, benötigt jede Entität ein DataSet, einen Reader für das Gateway, einen Converter, um die Daten zu konvertieren und einen Writer, um die Shopware 6 Struktur abzuspeichern. Die einzelnen DataSets der Entitäten werden dann in unterschiedliche DataSelections gesammelt, damit die Entitäten in der Datenauswahl in der Administration von Shopware 6 zur Verfügung stehen. Auch eigene Premapping-Reader können implementiert werden, falls Daten manuell durch den Benutzer gemapped werden müssen.
Weitere Information und HowTos gibt es in der Shopware 6 - Dokumentation:
HowTos:
- Eigenes Profil erstellen
- Shopware Converter dekorieren
- Shopware Profil erweitern
- Migration Connector erweitern
Dokumentationen:
Fazit
Wie man sieht können die einzelnen Bestandteile der Migration auf viele Wege erweitert und angepasst werden. Es ist alles für die Migration Deiner Plugins oder auch für die Migration aus anderen Quellsystemen vorbereitet. Um uns jeden Tag weiter zu verbessern, hier noch eine Aufruf in eigener Sache: Ob Du als Leser ein Pluginentwickler oder Shopware-Enthusiast bist, teste bitte die Migration aus, erweitere sie wenn nötig durch eigenen Anpassungen und Profile. Gib uns Feedback über Deine Erfahrungen und Verbesserungsvorschläge. Mit Deinem Feedback wird nicht nur die Migration etwas besser, sondern ganz Shopware 6.
Das könnte Dich auch interessieren:
Shopware for Magento developers
Bleibe auf dem Laufenden
Du interessierst Dich für weiteren Developer Content? Dann folge uns und erhalte aktuelle Informationen zu Produkt-Releases, Updates, Security-Hinweisen, der Academy und weiteren wichtigen technischen Insights aus dem Shopware Universum und der Community.