Main Image
Bild
Library over several levels with stair cases
03. August 2022

Daten von MS-SQL nach Drupal synchronisieren

by Jürgen Haas

Für ein bestehendes -Projekt bat ein Kunde um eine neue Funktion für eine Marketing-Kampagne, die er in Kürze starten wollte: In seinem ERP-System führt er eine riesige Liste von Projekten mit vielen Eigenschaften, die mit ihnen verbunden sind, und einer hohen Frequenz von Datenänderungen. Sowohl bestehende Projekte werden aktualisiert, als auch neue Projekte werden der Liste hinzugefügt. Diese Projekte sollten auf ihrer Drupal-Website beworben werden, aber es macht natürlich keinen Sinn, diese Daten manuell oder sogar zweimal zu pflegen.

Um die Sache etwas anspruchsvoller zu gestalten, sollten die Daten nicht nur in einer Ansicht angezeigt werden. Das wäre möglich gewesen, wenn man eine zweite Datenbank für die Drupal-Site konfiguriert und das Views- angewiesen hätte, diese externe Datenbank nach den Inhalten abzufragen. Stattdessen sollte jedes Projekt mit einer Landing Page versehen werden, auf der weitere Einzelheiten und ein Kontaktformular angezeigt werden, damit die Besucher ihr Interesse an dem Projekt bekunden können.

Dafür gibt es nur einen vernünftigen Ansatz: Jedes Projekt in der externen Datenbank muss zu einer Inhaltsentität in Drupal werden.

Noch nicht genug der Herausforderung? Dann lassen Sie mich Ihnen sagen, dass die externe Datenbank MS-SQL ist, das auf Azure gehostet wird. Als ob all die Microsoft-Infrastruktur und -Werkzeuge das wären, in dessen Nähe wir geliebten Drupal-Ingenieure kommen wollten. Aber das ist eine andere Geschichte.

Definieren des Lösungs-Stacks

Da es bei der Hauptanforderung um die Synchronisierung von Inhalten und die Erstellung von Entitäten in Drupal geht, gibt es nur eine Antwort darauf: Das Migrate-Modul von Drupal Core. Es mag einige überraschen, aber diese Modulgruppe ist nicht nur für einmalige Migrationen von z.B. Drupal 7 nach 9 geeignet. Migrate ist ein exzellentes Werkzeug, um Daten aus einer externen Quelle zu lesen, zu verarbeiten und in Drupal zu speichern - nicht nur einmal, sondern so oft wie nötig, und es enthält alle notwendigen Mechanismen, um bestehende und eventuell aktualisierte Datensätze zu erkennen. Dass es auch eine solide Rollback-Funktion enthält, sei nur der Vollständigkeit halber erwähnt, nicht weil es für dieses aktuelle Projekt erforderlich ist.

Damit blieb uns die Anforderung, mit einer MS-SQL-Datenbank zu kommunizieren und, sobald dies gelöst ist, Migrate eine SQL-Datenbank als Datenquelle für all seine Magie akzeptieren zu lassen. Gemäß dem alten Sprichwort "Dafür gibt es ein Modul" hatten wir das Glück, für jede der beiden Anforderungen eines zu finden:

Ausgestattet mit diesen 3 Komponenten, erwies sich die Implementierung als äußerst einfach.

Implementierungsschritte

Nachdem wir die zusätzlichen Module heruntergeladen und aktiviert haben, definieren wir zunächst die zusätzliche Datenbank in der bestehenden settings.php-Datei der Drupal-Website:

$databases['azure']['default'] = [
  'database' => 'customer365projects',
  'username' => 'DrupalServiceUser',
  'passwort' => 'PASSWORD',
  'prefix' => '',
  'host' => 'sqlcustomer365.database.windows.net',
  'port' => '1433',
  'namespace' => 'Drupal\\sqlsrv\\Driver\\\Database\\sqlsrv',
  'autoload' => 'modules/contrib/sqlsrv/src/Driver/Database/sqlsrv',
  'driver' => 'sqlsrv',
];

Das ist alles, was Sie tun müssen, vorausgesetzt, dass der Datenbank-Host vom Drupal-Host über TCP/IP erreichbar ist. Wenn das nicht der Fall ist, was sehr wahrscheinlich ist, dann muss Ihre IT-Abteilung entweder mit SSH oder mit VPN einen Tunnel vom Drupal-Host zum Datenbank-Host aufbauen. Aber das würde den Rahmen dieses Blogbeitrags sprengen.

Von nun an kann Ihre Drupal-Website mit der MS-SQL-Datenbank in Azure "sprechen". Nicht, dass dies für unser Projekt erforderlich gewesen wäre, aber um eine Vorstellung davon zu geben, was Sie tun müssten, wenn Sie benutzerdefinierten Code schreiben wollten, um von oder in diese Datenbank zu lesen und/oder zu schreiben:

$database = \Drupal\Core\Database\Database::getConnection('default', 'azure');
$query = $database->select('...');

Der letzte Schritt für uns war die Konfiguration des Migrationsmoduls, um Daten aus dieser Datenbank zu importieren. Wir haben eine Migrate-Konfiguration wie folgt erstellt:

id: Projekte
label: Projekte
migration_dependencies: { }
source:
  plugin: custom_sql_query
  Schlüssel: azure
  Schlüssel:
    - id
  sql_query: "SELECT *
        FROM projekte p
                 INNER JOIN extras e
                            ON p.id = e.id
        WHERE p.status='for-drupal'"
Ziel:
  plugin: entity:node
  standard_bundle: projekt
Prozess:
  Titel: Projekt
  aktualisiert: Zeitstempel
  feld_a: eigenschaft_a
  feld_b: eigenschaft_b
  feld_c: eigenschaft_c

Dies ist eine vereinfachte Version der Konfiguration, um die wichtigsten Bausteine dieser Lösung zu zeigen. Natürlich können Sie alle Möglichkeiten von Migrate nutzen, um Daten zu verarbeiten und in der Standarddatenbank von Drupal zu speichern.

Die wichtigsten Einstellungen für die Kommunikation mit unserer externen Datenbank sind in dieser Konfiguration die Quellen plugin, key und sql_query. Das Plugin custom_sql_query stammt aus dem installierten Modul, der Schlüssel azure bezieht sich auf den Schlüssel, den wir in den Einstellungen für diese Datenbank verwendet haben und die SQL-Abfrage ist völlig frei wählbar und hängt vom Datenmodell der externen Datenbank ab.

Wie geht es nun weiter?

drush migrate:import projects

Und du bist fertig. Wirklich!

Abschluss

Ein ziemlich komplexer Satz von Anforderungen wird mit nur zwei Zusatz-Modulen von drupal.org und zwei Konfigurationen in den Drupal-Einstellungen und für das Migrationsmodul von Drupal Core gelöst. Es ist kein eigener Code erforderlich. Und dennoch kann der Kunde nun alle 5 Minuten den Befehl migrate:import mit einer System-Crontab ausführen. Alle Projektdaten aus dem internen ERP-System werden auf der Drupal-Website angezeigt, immer korrekt und immer aktuell. Besser geht's nicht.

Tools

Neuen Kommentar hinzufügen