Импорт данных с фреймворком migrate. Владислав Богатырев

28
Импорт данных с фреймворком Migrate Владислав Богатырев http://donetsk.drupal.ua

Upload: drupalcampdn

Post on 08-May-2015

1.311 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Импорт данных с фреймворком Migrate. Владислав Богатырев

Импорт данных с фреймворком Migrate

Владислав Богатырев

http://donetsk.drupal.ua

Page 2: Импорт данных с фреймворком Migrate. Владислав Богатырев

Импорт данных с фреймворком Migrate

Владислав Богатырев

Ноябрь 2011

Page 3: Импорт данных с фреймворком Migrate. Владислав Богатырев

Задача доклада

• С какими проблемами я столкнусь при миграции данных на Drupal7?

• Что из это может решить Migrate?• Использовать ли Migrate ?

Page 4: Импорт данных с фреймворком Migrate. Владислав Богатырев

Структура доклада

• Задача, что мигрируем.• Проблемы• Выбор платформы.• Что такое Migrate.• Пример кода миграции.• Миграция множественных значений и сложных полей.• Сохранение связей при изменении ИД элементов. • Что еще может Migrate

   

Page 5: Импорт данных с фреймворком Migrate. Владислав Богатырев

Задача

Из некоторой структуры данных, (обычно это CMS на основе БД), скопировать в Drupal набор объектов.

Обычный набор, это :• ноды с их набором артибутов• термины таксономии• пользователи• комментарии• файлы• другие данные, как например оценки контента

пользователями• связи между всем перечисленным

                                                                Это значит, что ...

Page 6: Импорт данных с фреймворком Migrate. Владислав Богатырев

Проблемы

- вам нужно изучить внутреннюю структуру старой БД(скорее всего данные будут разбросаны по разным таблицам) - вам нужно знать API Drupal и выполнять импорт через него.- почти наверняка потребуется знание структуры хранения данных в Drupal- вам нужно написать код по копированию данных- вам нужно знать как изменились ИД объектов для сохранение связей- возможно, вы захотите использовать Batch API 

Page 7: Импорт данных с фреймворком Migrate. Владислав Богатырев

РешениеЭто же Drupal!  Давайте используем модуль для этого!

• Feeds http://drupal.org/project/feeds • Десятки плагинов для Feeds -) • Node Export (dev) http://drupal.org/project/node_export• Wordpress Migrate 

http://drupal.org/project/wordpress_migrate• Joomla to Drupal http://drupal.org/project/joomla• phpBB2Drupal (dev)

http://drupal.org/project/phpbb2drupal • Blogger Importer

http://drupal.org/project/blogger_importer  • TYPO3_migrate http://drupal.org/project/TYPO3_migrate• Migrate http://drupal.org/project/migrate 

Page 8: Импорт данных с фреймворком Migrate. Владислав Богатырев

Migrate (7.x-2.2)

- вся работа происходит в коде, это фреймворк- любой источник данных*- любая entity назначения*- работает с любыми полями*- умеет переводить старые ИД в новые - хорошая документация- ООП - много дополнительных классов на DO- Кое в чем может помочь migrate_extras * но иногда для этого придется определить свой класс :)

Page 9: Импорт данных с фреймворком Migrate. Владислав Богатырев

Как выглядит MigrateНемного вот так:

Page 10: Импорт данных с фреймворком Migrate. Владислав Богатырев

Как выглядит MigrateНо в основном так:

Page 11: Импорт данных с фреймворком Migrate. Владислав Богатырев

Начало работы

1. Устанавливаем модули: migrate, migrate_ui  2. Создаем свой модуль: 

3. Добавляем .inc файлы где будет располагаться код для миграции. 

1. /*2.  * You must implement hook_migrate_api(), setting the API level to 2, for3.  * your migration classes to be recognized by the Migrate module.4.  */5. function migrate_example_migrate_api() {6.   $api = array(7.     'api' => 2,8.   );9.   return $api;10.}11. 

 

Page 12: Импорт данных с фреймворком Migrate. Владислав Богатырев

Пример. Миграция нод.

1. abstract class BasicExampleMigration extends Migration {2.   public function __construct() {3.    4.     parent::__construct();5.  6.     $this->team = array(7.       new MigrateTeamMember('Liz Taster', '[email protected]', t('Product Owner')),8.       new MigrateTeamMember('Larry Brewer', '[email protected]', t('Implementor')),9.     );10. 11.    $this->issuePattern = 'http://drupal.org/node/:id:';12.  }13.}14. 

Определяем базовый класс с общими атрибутами и методами.

Page 13: Импорт данных с фреймворком Migrate. Владислав Богатырев

Пример. Миграция нод.

1. class BeerNodeMigration extends BasicExampleMigration {2.   public function __construct() {3.     parent::__construct();4.     $this->description = t('Beers of the world');5.     $this->dependencies = array('BeerTerm', 'BeerUser');6.  7.     // карта старых и новых ИД мигрируемых объектов8.     $this->map = new MigrateSQLMap($this->machineName,9.       array(10.        'bid' => array(11.          'type' => 'int',12.          'not null' => TRUE,13.          'description' => 'Beer ID.',14.          'alias' => 'b',15.        )16.      ),17.      MigrateDestinationNode::getKeySchema()18.    );19. 20.   

Класс миграции нод. (Начало)

Page 14: Импорт данных с фреймворком Migrate. Владислав Богатырев

1.  2.     // объект выборки данных из источника3.     $query = db_select('migrate_example_beer_node', 'b')4.              ->fields('b', array('bid', 'name', ...));5.     $query->...6.  7.     // определяем атрибут класса - источник данных8.     $this->source = new MigrateSourceSQL($query);9.  10.     // определяем атрибут класса - объект назначения данных11.     $this->destination = new MigrateDestinationNode('migrate_example_beer');12.  13.     // связываем поля источника и назначения14.     $this->addFieldMapping('title', 'name')15.          ->description(t('Mapping beer name in source to node title'));16.    17.     // другие простые поля определяются аналогично18.     ...19.  20.   }21. }22.  

Пример. Миграция нод.Класс миграции нод. (конец)

Page 15: Импорт данных с фреймворком Migrate. Владислав Богатырев

1. class BeerUserMigration extends BasicExampleMigration {2.   public function __construct() {3.     parent::__construct();4.     $this->description = t('Beer Drinkers of the world');5.     $this->map = new MigrateSQLMap($this->machineName,6.         array('aid' => array(7.                 'type' => 'int',8.                 'not null' => TRUE,9.                 'description' => 'Account ID.'10.                )11.             ),12.        MigrateDestinationUser::getKeySchema()13.    );14. 15.    // объект выборки данных из источника16.    $query = db_select('migrate_example_beer_account', 'mea')17.     ->fields('mea', array('aid', 'status', 'posted', 'name', 'nickname', ...));18.   19.    // определяем атрибут класса - источник данных20.    $this->source = new MigrateSourceSQL($query);21.   22.    // определяем атрибут класса - объект назначения данных23.    $this->destination = new MigrateDestinationUser();24. 25.    // связываем поля источника и назначения26.    $this->addFieldMapping('created', 'posted');27. 28.    ...29.  }30.}31. 

Пример. Миграция пользователей.

Page 16: Импорт данных с фреймворком Migrate. Владислав Богатырев

Ключевые моменты. Карта ИД.

1.     $this->map = new MigrateSQLMap($this->machineName,2.         array('aid' => array(3.                 'type' => 'int',4.                 'not null' => TRUE,5.                 'description' => 'Account ID.' 6.                 )7.              ),8.         MigrateDestinationUser::getKeySchema()9.     );10. 

Page 17: Импорт данных с фреймворком Migrate. Владислав Богатырев

Ключевые моменты. Источник и назначение.

1. // определяем атрибут класса - источник данных2. $this->source = new MigrateSourceSQL($query);3.  4. // определяем атрибут класса - объект назначения данных5. $this->destination = new MigrateDestinationUser();6.  

Page 18: Импорт данных с фреймворком Migrate. Владислав Богатырев

1.  // связываем поля источника и назначения2. $this->addFieldMapping('created', 'posted');3.  

Ключевые моменты. Связывание полей.

• Маппинг сложных полей• Маппинг полей с множественными значениями• Значения по умолчанию• Обработка поля источника и поля назначения

перед сохранением. o Дополнительные обращение к БД o Работа с объектом новой entity  

Page 19: Импорт данных с фреймворком Migrate. Владислав Богатырев

1.$query = db_select('migrate_example_beer_node', 'b')2. 3.  ->fields('b', array('bid', 'name', ... ));4. 5.$query->leftJoin('migrate_example_beer_topic_node',6. 7.  'tb', 'b.bid = tb.bid');8. 9.$query->groupBy('tb.bid');10. 11.$query->addExpression('GROUP_CONCAT(tb.style)', 'terms');12. 13. 14. 15.$this->addFieldMapping('migrate_example_beer_styles', 'terms')16. 17.  ->separator(',');18. 19. 

Маппинг полей с множественными значениями на примере таксономии.

Page 20: Импорт данных с фреймворком Migrate. Владислав Богатырев

1. public function prepareRow($current_row) {2.  3.     parent::prepareRow($current_row);4.  5.     // Добавляем разделенные запятой термины к объекту рядя источника6.     // с помощью кастомного метода7.     $current_row->terms = $this->get_node_term_names(8.       $current_row->nid,9.       array(CRNAAccreditationTermMigration::$source_vocabulary_vid)10.    );11. 12.    return TRUE;13.  }14.}15. 

Маппинг полей с множественными значениями на примере таксономии.

1. $this->addFieldMapping('migrate_example_beer_styles', 'terms')2.   ->separator(',');

 prepare(stdClass $account, stdClass $row)

Page 21: Импорт данных с фреймворком Migrate. Владислав Богатырев

Маппинг полей.

 prepare(stdClass $entity, stdClass $row)

Page 22: Импорт данных с фреймворком Migrate. Владислав Богатырев

Перевод ИД.

1. // объявляем зависимость2. $this->dependencies = array('BeerTerm', 'BeerUser');3.  4. // при маппинге поля просим фреймврок заменять значение 'aid' на новое,5. // из таблицы карты миграции и устанавливаем значение по умолчанию6. $this->addFieldMapping('uid', 'aid')7.   ->sourceMigration('BeerUser')8.   ->defaultValue(1);9.  

В конструкторе класса миграции BeerNodeMigration:

Page 23: Импорт данных с фреймворком Migrate. Владислав Богатырев

Перевод ИД.

1.$this->addFieldMapping('pid', 'cid_parent')2. 3.  ->sourceMigration('BeerComment')4. 5.  ->description('Parent comment.');6. 7. 

В конструкторе класса миграции BeerCommentMigration:

Page 24: Импорт данных с фреймворком Migrate. Владислав Богатырев

Миграция сложных полей на примере  addressfield.

Для миграции сложного поля, необходимо:• проверить существование соответвующего класса• создать класс в случае необходимости• использовать соответвующий синтаксис маппинга

ИЛИ

Использовать метод  prepare(stdClass $entity, stdClass $row)

Page 25: Импорт данных с фреймворком Migrate. Владислав Богатырев

Миграция сложных полей на примере  addressfield.

1. $arguments = array(2.   'administrative_area' => array('source_field' => 'province'),3.   'locality' => array('source_field' => 'city'),4.   'thoroughfare' => array('source_field' => 'street'),5.   'premise'  => array('source_field' => 'additional'),6.   'postal_code'  => array('source_field' => 'postal_code'),7. );8. $this->addFieldMapping(‘field_address’, ‘country’)9.   ->arguments($arguments)10.  ->description(t('Mapping field_address'));11. 

Маппинг поля в конструкторе.

Кастомный класс для маппинга addrressfield >>>

Page 26: Импорт данных с фреймворком Migrate. Владислав Богатырев

Миграция сложных полей на примере  addressfield.

1. class MigrateAddressFieldHandler extends MigrateFieldHandler {2.   public function __construct() {3.     $this->registerTypes(array('addressfield'));4.   }5.  6.   public function prepare($entity, array $field_info, array $instance, array $values) 

{7.     $arguments = array();8.     if (isset($values['arguments'])) {9.       $arguments = array_filter($values['arguments']);10.      unset($values['arguments']);11.    }12.    $language = $this->getFieldLanguage($entity, $field_info, $arguments);13. 14.    // Setup the standard Field API array for saving.15.    $delta = 0;16.    foreach ($values as $value) {17.      $return[$language]

[$delta] = array('country' => $value) + array_intersect_key($arguments,$field_info['columns']);

18.      $delta++;19.    }20. 21.    return isset($return) ? $return : NULL;22.  }23.}24. 

Page 27: Импорт данных с фреймворком Migrate. Владислав Богатырев

Что еще может Migrate

• Работа с файлами• Поддержка XML, JSON, CSV,    • Поддержка с различных типов БД источника (MSSQL,

Oracle)• Миграция alias'ов• Интеграция с Drush• Откат импорта • Интерфейс для контроля прогресса и маппинга • and even more...

 

Page 28: Импорт данных с фреймворком Migrate. Владислав Богатырев

Импорт данных с фреймворком Migrate

Владислав Богатырев

Ноябрь 2011

It is powerful.Use it!