Миграция: в чем разница между prepare () и prepareRow ()?


8

Используя модуль Migrate: я понимаю, что prepareRow () запускает фильтр для строки и должен возвращать TRUE или FALSE в зависимости от некоторых условий, что позволяет переносить строку или нет, но кто-то может уточнить:

  • когда использовать готовить ()
  • когда использовать prepareRow ()
  • почему вы не добавите фильтр в исходный запрос SQL для фильтрации результатов строки, которые вы можете удалить / включить в любой из вышеперечисленных

Спасибо!


1
Одна из причин не выполнять фильтрацию при запросе sql - добавить сопоставление для строк, которые вы решили пропустить. Например, я импортирую пользователей на существующий сайт. Я хочу пропустить пользователей, которые уже существуют в месте назначения, и я хочу добавить сопоставление, как если бы пользователь был фактически импортирован , поэтому другие миграции в зависимости от этого работают без проблем.
Джонатан

Ответы:


9

Все это подробно описано в документации по классам миграции, предоставленной проектом. В частности, на странице методов Commononly Implemented Migration, которая говорит следующее и включает дополнительные простые примеры реализации функций. Из документов ...

функция prepare_row ($ row)

Метод prepareRow () вызывается методом исходного класса next () после загрузки строки данных. Аргумент $ row является объектом stdClass, содержащим необработанные данные, предоставленные источником. Есть две основные причины для реализации prepareRow ():

  1. Чтобы изменить строку данных, прежде чем она пройдет через любые другие методы и обработчики: например, выборку связанных данных, разделение полей источника, объединение или создание новых полей источника на основе некоторой логики.
  2. Условно пропустить строку (вернув FALSE).

функция подготовить ($ entity, stdClass $ row)

Метод prepare () класса Migration вызывается методом prepare () класса назначения после того, как он вызвал все методы prepare () уровня поля, и непосредственно перед сохранением объекта назначения. Аргумент $ entity - это объект назначения, который заполняется начальными сопоставлениями полей и обрабатывается методами уровня поля; Аргумент $ row - это объект, содержащий данные после prepareRow () и любых обратных вызовов. Метод prepare () - это последний шанс манипулировать целевым объектом перед его сохранением в базе данных Drupal. Важно помнить, что, поскольку он вызывается после обработчиков полей, поля будут иметь полностью развернутые формы (т. Е. В Drupal 7 значение текстового поля будет равно, $entity->field_textual_data['und'][0]['value']а не просто) $entity->field_textual_data).

Модуль Migrate - это инфраструктура, которая позволяет инкапсулировать процесс миграции из исходного фрагмента данных в место назначения и конфигурацию. Миграция состоит из:

  • определить, где данные
  • определить, куда должны идти данные
  • получить часть данных (строка)
  • очистить данные
  • начать перемещать данные (скажем, в сущность)
  • на самом деле переместить данные
  • после перемещения данных выполните дополнительные действия

API предоставляет хуки для воздействия на данные, перемещаемые в этом жизненном цикле миграции. Исключая данные из миграции через ваш первоначальный запрос, вы ограничиваете степень контроля над всеми данными, которые вы можете переместить. Для суб-миграций вы можете найти это полезным. Но при общей миграции контента вы бы хотели, чтобы ваша миграция была как можно более всеобъемлющей.


Спасибо Tenken, именно то, что я искал. Цените мысли об удалении элементов из исходного запроса.
user4984 15.07.14

6

Если вы можете выбрать правильную строку, написав ее в запросе, переходите к ней, однако preprareRow () можно использовать в более сложных системах, где может потребоваться несколько параметров, прежде чем строка будет перенесена. В таком случае легче пройти через все строки и выполнить логику для каждой строки.

prepare () запускается после prepareRow () и является вашим последним шансом изменить сущность перед ее сохранением в базе данных.

Дополнительную информацию об этом можно найти здесь: https://www.drupal.org/node/1132582.


Я нашел это, чтобы быть кратким и понятным
Джонатан Элмор

3

Это частичный ответ и никоим образом не полный. Я также хотел бы узнать больше об обоих из них. Так что это может быть частью дискуссии; хотя я написал как ответ, а не как комментарий из-за следующих фрагментов кода и примеров того, как я использовал вышеупомянутые классы.

Позвольте мне проиллюстрировать некоторые из моих применений prepareRow () как ... что делает как говорится.

Недавно я давал некоторые данные для импорта из не друпальной базы данных. Сущность, к которой я добавляю, требует ввода полей, которых у меня нет при импорте данных.

Поэтому, прежде чем мой исходный класс будет создан, я могу добавить

  $source_fields = array(
    'changed' => t('Timestamp of when the change was made.'),
    'created' => t('Timestamp of when the node was Created.'),
 );

а затем в функции prepareRow я могу сделать следующее

$nowtimestamp = mktime(date('Y-m-d'));
$row->changed = $nowtimestamp;
$row->created = $nowtimestamp;

Вы также можете запускать операторы php if / else здесь, если это необходимо.

Я также использовал функцию подготовки в своем коде и использую ее для присвоения значений сущности.

$account->field_job_location [und][0]['tid'] = $row->job_location_tid;

Я только использовал это в этом сценарии, так как я сделал свой собственный плагин для нодов.

Также, если вам нужно сделать расчеты, вы можете сделать это в prepareRow, который запускается перед prepare ().

Например, в импорте у меня было значение, помеченное как «Город», - и я мог превратить его в идентификатор термина.

 if ($TownCity == 'London' ){
            $row->job_location_tid = '10';
      } else {
        $row->job_location_tid = '11';
      } 

Надеюсь, это поможет.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.