Настройка модуля Migrate для миграции контента в Drupal

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Настройка модуля Migrate для миграции контента в Drupal
Сложная
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1214
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    852
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    823
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    815

Настройка модуля Migrate для миграции контента в Drupal

Drupal Migrate — встроенная ETL-система (Extract, Transform, Load) для импорта данных из любых источников: старых версий Drupal, WordPress, CSV, XML, JSON, SQL-баз сторонних систем. Конфигурируется через YAML, расширяется плагинами.

Архитектура Migrate

Source — откуда читаем данные (CSV, SQL, JSON, Drupal 7 DB) Process — трансформация: маппинг полей, конвертация, обогащение Destination — куда записываем (Node, Term, User, File, Config)

Каждая миграция — отдельный YAML-файл в config/install/migrate_plus.migration.*.yml.

Установка

composer require drupal/migrate_plus drupal/migrate_tools drupal/migrate_source_csv
drush en migrate migrate_plus migrate_tools -y

Миграция из CSV

Файл config/install/migrate_plus.migration.articles_from_csv.yml:

id: articles_from_csv
label: 'Статьи из CSV'
migration_group: content_import

source:
  plugin: csv
  path: 'public://import/articles.csv'
  ids:
    - external_id
  header_row_count: 1
  column_names:
    - external_id
    - title
    - body
    - category
    - publish_date
    - image_url

process:
  title: title
  'body/value': body
  'body/format':
    plugin: default_value
    default_value: full_html
  created:
    plugin: format_date
    source: publish_date
    from_format: 'd.m.Y'
    to_format: 'U'
  status:
    plugin: default_value
    default_value: 1
  field_category:
    plugin: migration_lookup
    migration: categories_from_csv
    source: category
  field_image:
    plugin: download
    source:
      - image_url
      - '@filename'
    destination:
      plugin: 'public://images'
    rename: true

destination:
  plugin: 'entity:node'
  default_bundle: article

migration_dependencies:
  required:
    - categories_from_csv

Кастомный Source плагин

Для нестандартных источников — кастомный плагин:

// src/Plugin/migrate/source/ExternalApiSource.php
namespace Drupal\mymodule\Plugin\migrate\source;

use Drupal\migrate\Plugin\migrate\source\SourcePluginBase;

/**
 * @MigrateSource(
 *   id = "external_api",
 *   source_module = "mymodule"
 * )
 */
class ExternalApiSource extends SourcePluginBase {
    public function getIds(): array {
        return ['id' => ['type' => 'integer']];
    }

    public function fields(): array {
        return [
            'id' => 'ID записи',
            'title' => 'Заголовок',
            'content' => 'Содержимое',
            'tags' => 'Теги (через запятую)',
        ];
    }

    protected function initializeIterator(): \Iterator {
        $page = 0;
        do {
            $response = \Drupal::httpClient()->get(
                'https://api.external.com/posts?page=' . $page,
                ['headers' => ['Authorization' => 'Bearer ' . $this->configuration['api_key']]]
            );
            $data = json_decode($response->getBody(), true);
            $items = $data['items'];

            foreach ($items as $item) {
                yield $item;
            }

            $page++;
        } while (!empty($items) && $page < $data['total_pages']);
    }
}

Кастомный Process плагин

// src/Plugin/migrate/process/ExtractFirstImage.php
namespace Drupal\mymodule\Plugin\migrate\process;

use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;

/**
 * @MigrateProcessPlugin(id = "extract_first_image")
 */
class ExtractFirstImage extends ProcessPluginBase {
    public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property): ?string {
        if (preg_match('/<img[^>]+src=["\']([^"\']+)["\']/', $value, $matches)) {
            return $matches[1];
        }
        return NULL;
    }
}

Запуск и мониторинг

# Список доступных миграций
drush migrate:status

# Запуск конкретной миграции
drush migrate:import articles_from_csv

# Запуск всех из группы
drush migrate:import --group=content_import

# С обновлением уже мигрированных записей
drush migrate:import articles_from_csv --update

# Откат миграции
drush migrate:rollback articles_from_csv

# Статус с прогрессом
drush migrate:status --format=table

Обработка ошибок

# Просмотр ошибок миграции
drush migrate:messages articles_from_csv

# Пропуск записей с ошибками и продолжение
drush migrate:import articles_from_csv --continue-on-failure

Миграция медиафайлов

# Шаг 1: миграция файлов
id: files_migration
source:
  plugin: csv
  path: 'public://import/files.csv'
process:
  filename:
    plugin: callback
    callable: basename
    source: file_url
  uri:
    plugin: download
    source:
      - file_url
      - '@filename'
    destination:
      plugin: 'public://migrated'
destination:
  plugin: 'entity:file'

# Шаг 2: в миграции нод
field_image:
  plugin: migration_lookup
  migration: files_migration
  source: file_id

Incremental migration

Чтобы при повторном запуске мигрировались только новые записи, источник должен отслеживать highwater mark:

source:
  plugin: csv
  path: 'public://import/articles.csv'
  ids:
    - external_id
  track_changes: true  # перемигрировать при изменении строки

# Или через highwater mark (для дат)
highwaterProperty:
  name: updated_at
  alias: u

Сроки

Простая миграция из CSV (500–5000 записей) — 2–3 дня. Сложная миграция из нескольких источников с кастомными плагинами и трансформациями — 1–2 недели.