Рейтинг:0

Использование миграции (также) для обновления узлов, которые уже существуют в Drupal

флаг cn

Я нахожусь в процессе переноса базы данных, отличной от 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
пункт назначения:
  плагин: 'сущность: узел' 
  перезаписать_свойства:
    - поля_страниц
    - страна_поля 
миграция_зависимости: ноль

У меня есть две проблемы с этой миграцией:

  1. Даже если 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); Множество
  1. Я преодолеваю это, только чтобы не иметь возможности добавить в существующую Книгу правильный термин таксономии в список 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 к перезаписать_свойства, конечно, он перезаписывается, и мы теряем все предыдущие члены.

Я не вижу способа обновить, добавив значение в поле с несколькими значениями.

Любая помощь? Спасибо Вт

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.