この記事はDrupal Advent Calendar 2018 11日目に投稿する予定でしたが、投稿するのが遅くなってしまい大変申し訳ありませんでした。

今回書く記事ですが、現在Drupal 6で運用されていたサイトをDrupal 8に移行する作業を行っています。

そこで、Drupal 6のデータベースからDrupal 8へのデータベースへ移行する際に、

Migrating data from a SQL sourceを参考に実施しました。そこで学んだことを何回かに分けて書いて行きます。

Migrate APIについてはDrupal8 Migrate API 事始めというページに詳しく記載していただいているので、こちらをご参照ください。


概要

まず、概要についてですが、Drupal 8ではマイグレーションさせる方法は色々あります。その中でも今回はタイトルにあるように外部のデータベースからノードなどを移行する方法をご紹介します。

前提条件として必要となってくることは、上記で紹介させていただいたDrupal8 Migrate API 事始めのMigrate API でマイグレーションを行うまでの流れをご参照ください

Migrate API でマイグレーションを行うまでの流れが準備できましたら、Drupal 6で作成されたblogを移行していきましょう。


Custom Source Pluginの作成

ここではCustom Source Pluginの作成方法について説明していきます。

こちらはDrupal 6やDrupal 7の移行させたいデータを定義したり、また次の記事でご紹介するpreparerow()を用いて、データをカスタマイズして追加するといったことができるカスタムモジュールとなっています。

例として、今回はDrupal 6でのブログ記事をDrupal 8にマイグレーションさせるtest_blog_migrationというカスタムモジュールを作成しました。 このカスタムモジュールのサブディレクトリ( src/Plugin/migrate/source )にTestMigrate.phpを保存し、こちらに実装内容を記載して行きます。

以下、ディレクトリ内容です

modules
└── custom
    └──test_blog_migration
        ├── src
        │   └── Plugin
        │       └── migrate
        │           └── source
        │               └── TestMigrate.php
        └── test_blog_migration.info.yml


実装内容

上記のクラスやメソッドを用いて実装します。


SqlBaseクラス

SQLソースからマイグレーションさせるにはSqlBaseクラスを継承する必要があります

<?php

namespace Drupal\test_blog_migration\Plugin\migrate\source;

use Drupal\migrate\Plugin\migrate\source\SqlBase;
use Drupal\migrate\Row;

/**
 * ブログに関するコンテンツをマイグレーション.
 *
 * @MigrateSource(
 *   id = "test_blog",
 * )
 */
class TestMigrate extends SqlBase {

ここで@MigrateSourceidを指定する必要があります。これは後ほどYAMLファイルに記載することなので忘れずに記載してください。


query()

今回はDrupal 6に登録されているノードの中でもblogというコンテンツタイプのものをマイグレーションさせたいとします。ですので、その必要な情報を取得できるようクエリを記載するところになります。

/**
 * ブログに関するコンテンツをマイグレーション.
 *
 * @MigrateSource(
 *   id = "test_blog"
 * )
 */
class TestMigrate extends SqlBase {

  /**
   * {@inheritdoc}
   */
  public function query() {

    $query = $this->select('node', 'n');
    $query->join('node_revisions', 'nr', 'nr.nid = n.nid');
    $query->fields('n', [
      'nid',
      'vid',
      'type',
      'language',
      'title',
      'uid',
      'status',
      'created',
      'changed',
      'comment',
    ])
      ->fields('nr', [
        'body',
        'teaser',
        'format',
      ])
      ->condition('n.type', 'blog', '=');

    return $query;

  }

fields()

ソース上の利用可能なfieldsを返します。

これはquery()に記載したクエリ情報を記載するメソッドです。

  /**
   * {@inheritdoc}
   */
  public function fields() {

    $fields = [
      'nid' => $this->t('nid'),
      'vid' => $this->t('vid'),
      'type' => $this->t('type'),
      'language' => $this->t('language'),
      'title' => $this->t('title'),
      'uid' => $this->t('uid'),
      'status' => $this->t('status'),
      'created' => $this->t('created'),
      'changed' => $this->t('changed'),
      'comment' => $this->t('comment'),
      'body' => $this->t('blog body'),
      'teaser' => $this->t('blog summary'),
      'format' => $this->t('blog format'),
    ];

    return $fields;
  }

サイト構築→Migrations→Edit migration groupからMigrationさせるものをクリックすると下記の画像にソースという場所があるかと思います。そこにfields()に記載したことが表示されます。画像

getIds()

Drupal 8で定義されている主キーに対応するフィールドの定義を返す必要があります。Drupal 6のノードテーブルの主キーはnidであるため、今回はnidを定義します

  /**
   * {@inheritdoc}
   */
  public function getIds() {
    return [
      'nid' => [
        'type' => 'integer',
        'alias' => 'n',
      ],
    ];
  }

移行元データベースへの接続定義

ここまでできたら、次は移行元のデータベースの情報を記載します。

settings.phpに以下のように記載してください

// Drupal 8のデータベース情報.
$databases['default']['default'] = array (
  'database'  => 'drupal8-database-name',
  'username'  => 'drupal8-database-username',
  'password'  => 'drupal8-database-password',
  'host'      => 'drupal8-database-server',
  'port'      => '3306',
  'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
  'driver'    => 'mysql',
);

// Drupal 6のデータベース情報.
$databases['migrate']['default'] = array (
  'database'  => 'source-database-name',
  'username'  => 'source-database-username',
  'password'  => 'source-database-password',
  'host'      => 'source-database-server',
  'port'      => '3306',
  'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
  'driver'    => 'mysql',
);

Drupal 8でのDatabase APIにより、複数のデータベースの接続が行えます。

keymigrate(ここは任意)とし、次のブログで記載するYAMLファイルにKey: migrateと記載すれば、$databases['migrate']['default']に記載しているデータベースから情報が取得されます。


以上、Drupal 8 Migrate APIを利用したD6データベースのマイグレーション その1でした。

次回、マイグレーション実行する際のYAMLファイルについての記事を書きたいと思います。

ここまで読んでいただき、ありがとうございました。