Я нахожусь в процессе переноса базы данных, отличной от Drupal, на Drupal 9.
Исходная база данных содержит, среди прочего, таблицу Книг (с обычной информацией) и отдельную таблицу (не спрашивайте почему) для Книг о путешествиях. Первый из них содержит 10 000 записей и был успешно перенесен из книги.csv
в Друпал. Последний (путевые книги.csv
) составляет всего 200 записей.
Что интересно (sic!), так это то, что большинство книг о путешествиях также находятся в таблице «Книги» с некоторыми новыми полями в таблице «Книги о путешествиях», в частности, страна и количество страниц (опять же!).
В Drupal у нас есть таксономия для тип книги
с такими вещами, как романтика
, приключение
, правдивые истории
, преступление
, поэзия
и т.д.. а также книга путешествий
.
Книги из книги.csv
уже в Drupal, с новыми узлами и правильными терминами таксономии, примененными к полю field_book_type
что, конечно же, является многозначным полем.
Теперь я хочу мигрировать путевые книги.csv
в Drupal, но:
- если книга уже существует (ищите по названию, так как идентификаторы в исходных таблицах были другими!), просто обновите узел в Drupal, добавив термин таксономии
travel_book
- если книги нет в Drupal, создайте ее и просто установите термин таксономии
travel_book
До сих пор мне удавалось делать это с помощью пользовательского плагина Destination, а не только с конфигурацией миграции YAML.
Это то, что я надеялся использовать:
UUID: d66124cf-232b-4080-911c-1d26aefd0246
код языка: en
статус: правда
зависимости: { }
идентификатор: quote_fornitore_voucher_csv_import
класс: ноль
field_plugin_method: ноль
cck_plugin_method: ноль
migration_tags: ноль
миграция_группа: книги
label: 'Импорт книг о путешествиях'
источник:
плагин: csv
путь: /Users/walter/travel_books.csv
разделитель: ','
вложение: '"'
header_offset: 0
идентификаторы:
- я бы
поля:
-
имя: идентификатор
label: 'Уникальный идентификатор'
-
название: book_title
-
название: страна
-
имя: страницы
-
Название: синопсис
.....
константы:
travel_book: 'Книга путешествий'
процесс:
тип:
плагин: default_value
default_value: книга
field_pages: страницы
field_country: страна
название: book_title
field_book_type:
плагин: entity_lookup
entity_type: таксономия_термин
комплект: book_type
bundle_key: видео
источник: константы/travel_book
нид:
плагин: entity_generate
entity_type: узел
комплект: книга
bundle_key: тип
ключ_значения: заголовок
источник: book_title
доступ_проверить: 0
пункт назначения:
плагин: 'сущность: узел'
перезаписать_свойства:
- поля_страниц
- страна_поля
миграция_зависимости: ноль
У меня есть две проблемы с этой миграцией:
- Даже если
entity_generate
находит правильный существующий узел для текущей книги, механизм миграции все еще пытается СОЗДАТЬ новый узел с тем же NID и, конечно же, завершается с ошибкой SQL большого красного цвета.
23000]: Нарушение ограничения целостности: 1062 Дублирующаяся запись «2662» для ключа «PRIMARY»: ВСТАВИТЬ В «узел» («nid», «vid», «type», «uuid», «langcode») VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4); Множество
- Я преодолеваю это, только чтобы не иметь возможности добавить в существующую Книгу правильный термин таксономии в список
field_book_type
.
Я проследил проблему с 1 в том, что Сущность применятьIsNew
установите значение Истина. Или, по крайней мере, это то, что я нашел. Я написал подключаемый модуль назначения, который на основе новой конфигурации может заставить вновь созданный объект принуждениеИсНью = ЛОЖЬ
и, кажется, работает так, как ожидалось. Книги о путешествиях, которых нет в Books в nDrupal, создаются, а уже существующие обновляются с полями страницы
и страна
обновлено.
Я думаю, это соответствующий код.
абстрактный класс EntityBase реализует EntityInterface {
...
публичная функция isNew () {
вернуть !пусто($this->enforceIsNew) || !$это->идентификатор();
}
...
Несмотря на то, что есть идентификатор, который устанавливается нид
процесс, для параметра forceIsNew установлено значение ПРАВДА
и поэтому isNew() возвращает True.
<?php
пространство имен Drupal\migrate_books\Plugin\migrate\destination;
используйте Drupal\Core\Entity\Entity;
используйте Drupal\Core\Entity\EntityInterface;
используйте Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
используйте Drupal\migrate\Plugin\MigrationInterface;
используйте Drupal\migrate\Row;
используйте Symfony\Component\DependencyInjection\ContainerInterface;
/**
* @MigrateDestination(
* id = "update_node"
* )
*/
класс UpdateNodeDestination расширяет EntityContentBase {
/** @var строка $entityType */
общедоступный статический $entityType = 'узел';
защищенная функция updateEntity(EntityInterface $entity, Row $row) {
$entity = parent::updateEntity($entity, $row);
//проверяем параметр..
if(!empty($this->configuration['prefer_update']) && $this->configuration['prefer_update']){
// заставить НЕ применять NEW. Это позволит избежать двойной вставки уже существующих узлов (что приведет к
// при нарушении целостности от MySQL
$entity->enforceIsNew(FALSE);
}
вернуть $сущность;
}
}
и YAMLS изменен с моим плагином и новым параметром Prefer_update
пункт назначения:
плагин: update_node
Prefer_update: правда
перезаписать_свойства:
- поля_страниц
- страна_поля
но мне кажется, что должно быть проще. Я явно что-то упускаю. Я уверен, что это довольно стандартный вариант использования, поэтому его можно/должно полностью реализовать в YAML.
Во-вторых, я до сих пор не могу добавить правильный book_type
в список существующих тегов.
Если я добавлю field_book_type
к перезаписать_свойства
, конечно, он перезаписывается, и мы теряем все предыдущие члены.
Я не вижу способа обновить, добавив значение в поле с несколькими значениями.
Любая помощь?
Спасибо
Вт