Wie überspringt man eine Zeile, wenn die übergeordnete Entität während einer Drupal 8-Migration nicht existiert?
Mit Drupal 8 können Sie inkrementelle Migrationen durchführen und Datensätze aktualisieren, die sich seit der letzten Migration geändert haben. Wenn Sie in der Zwischenzeit solche Datensätze in Drupal 8 löschen, kann eine Migrationsaktualisierung fehlschlagen.
Wir sind auf dieses Problem gestoßen, als wir migrierte Forumsknoten aktualisieren wollten, die in der Zwischenzeit weitere Kommentare auf der Drupal 6 Quellseite erhalten hatten. Deren übergeordneter Knoten existierte in Drupal 8 nicht mehr:
TypeError: Argument 1 übergeben an Drupal\forum\ForumIndexStorage::updateIndex()
muss das Interface Drupal\node\NodeInterface implementieren, null gegeben,
aufgerufen in /core/modules/forum/forum.module
in Zeile 272 in Drupal\forum\ForumIndexStorage->updateIndex()
(Zeile 92 von /core/modules/forum/src/ForumIndexStorage.php)
#0 /core/modules/forum/forum.module(272):
Drupal\forum\ForumIndexStorage->updateIndex(NULL)
Um solche Fehler zu vermeiden, haben wir das Prozess-Plugin skip_row_if_not_exist geschrieben. Sie können den Entitätstyp und die Eigenschaft, auf die geprüft werden soll, sowie eine Migrationsmeldung konfigurieren:
<?php
namespace Drupal\migrate_custom\Plugin\migrate\process;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;
use Drupal\migrate\MigrateSkipRowException;
/**
* Überspringt die Verarbeitung der aktuellen Zeile, wenn ein Zielwert nicht vorhanden ist.
*
* Das Prozess-Plugin skip_row_if_not_exist prüft, ob ein Wert vorhanden ist. Wenn der
* Wert existiert, wird er zurückgegeben. Andernfalls wird eine MigrateSkipRowException
* geworfen.
*
* Verfügbare Konfigurationsschlüssel:
* - Entität: Die Zielentität, nach der gesucht werden soll.
* - Eigenschaft: Die zu prüfende Eigenschaft der Zielentität.
* - message: (optional) Eine Nachricht, die in der Tabelle {migrate_message_*}
* für diese Zeile protokolliert werden soll. Wenn nichts angegeben wird, wird nichts in der Nachrichtentabelle protokolliert.
*
* Beispiel:
* Kommentare für migrierte Knoten, die am Zielort nicht mehr existieren, nicht importieren.
* Ziel existieren.
*
* @code
* process:
* entity_id:
* -
* Plugin: migration_lookup
* Migration:
* - d6_node
* Quelle: nid
* -
* # Prüfen, ob ein Knoten in der Zieldatenbank existiert.
* plugin: skip_row_if_not_exist
* Entität: node
* Eigenschaft: nid
* message: 'Kommentierte Entität nicht gefunden.'
* @endcode
*
* Dies gibt die Knoten-ID zurück, wenn sie existiert. Andernfalls wird die Zeile
* uebersprungen und die Nachricht "Kommentierte Entitaet nicht gefunden." wird in der
* Nachrichtentabelle protokolliert.
*
* @see \Drupal\migrate\Plugin\MigrateProcessInterface
*
* @MigrateProcessPlugin(
* id = "skip_row_if_not_exist",
* handle_multiples = TRUE
* )
*/
class SkipRowIfNotExist extends ProcessPluginBase {
protected $entity = 'Knoten';
protected $property = 'nid';
function __construct($configuration, $plugin_id, $plugin_definition) {
Elternteil::__construct($konfiguration, $plugin_id, $plugin_definition);
if (!empty($configuration['entity'])) {
$this->entity = $configuration['entity'];
}
if (!empty($configuration['property'])) {
$this->Eigenschaft = $Konfiguration['Eigenschaft'];
}
}
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
$count = \Drupal::entityQuery($this->entity)
->condition($this->property, $value)
->accessCheck(FALSE)
->count()
->execute();
if (!$count) {
$message = isset($this->configuration['message']) ? $this->configuration['message'] : '';
throw new MigrateSkipRowException($message);
}
return $value;
}
}
Beispiel
Um zu prüfen, ob der übergeordnete Knoten eines Kommentars existiert, würde man folgendes tun:
- Kopieren Sie /core/modules/comment/migration_templates/d6_comment.yml in ein eigenes Migrationsmodul.
- Ersetzen Sie entity_id: nid durch zwei Prozess-Plugins.
- Suchen Sie die Ziel-Nid des übergeordneten Knotens in der Migrations-Zuordnungstabelle
- Überspringe die ganze Zeile, wenn der Knoten nicht existiert
Vor (Auszug)
process:
# Wenn Sie diese Datei verwenden, um eine benutzerdefinierte Migration zu erstellen, sollten Sie das
# das Feld cid entfernen, um inkrementelle Migrationen zu ermöglichen.
cid: cid
pid:
plugin: migration_lookup
Migration: d6_Kommentar
Quelle: pid
Entity_id: nid
Nachher (Auszug)
process:
# Wenn Sie diese Datei verwenden, um eine benutzerdefinierte Migration zu erstellen, sollten Sie das
# das Feld cid entfernen, um inkrementelle Migrationen zu ermöglichen.
cid: cid
pid:
plugin: migration_lookup
Migration: d6_Kommentar
Quelle: pid
Entitäts_id:
-
Plugin: Migration_Ansicht
Migration:
- d6_node
Quelle: nid
-
plugin: skip_row_if_not_exist
Entität: node
Eigenschaft: nid
Meldung: 'Kommentierte Entität nicht gefunden.'
Neuen Kommentar hinzufügen