Cómo migrar contenido de diferentes fuentes hacia Drupal utilizando el módulo Migrate

June 18, 2021

Share

Table of contents

Quick Access

En algunas ocasiones necesitamos migrar datos desde una fuente conocida a nuestro sitio en **Drupal 7**, es una tarea que puede llevar varias horas y más si no se tienen conocimientos sobre migraciones y las diferentes fuentes de datos posibles. El módulo **Migrate** de Drupal nos acorta esas horas de trabajo y nos presenta una interfaz muy sencilla de utilizar y a la vez muy poderosa. Veamos con un ejemplo cómo podemos migrar desde una base de datos una tabla con los datos necesarios para crear nodos de un tipo de contenido en nuestro sitio. Para este ejemplo tengo un tipo de contenido llamado *Activities* donde solamente tengo un título, un cuerpo y una imagen. Teniendo en cuenta los campos de mi tipo de contenido, puedo mapear los datos contenidos en la tabla “activities” de la base de datos que necesito migrar. drupal migrate Con esto claro, vamos a habilitar el módulo **Migrate** y luego** Migrate UI** el cual nos ofrece una interfaz para administrar las migraciones. [prism:javascript] drush en migrate -y drush en migrate_ui -y [/prism:javascript] ¡Vamos a escribir código! Creamos un módulo custom al que llamaremos *migrate_activities* e incluimos como dependencia al módulo de migrate. En *migrate_activities.info* [prism:javascript] dependencies[] = migrate [/prism:javascript] Nuestro nuevo módulo tendrá 4 archivos, como se ven en la siguiente imagen: drupal migrate El archivo *migrate_activities.module* esta vez estará vacío, solamente agregamos una descripción. Y porqué está vacío? Porque en esta ocasión solamente utilizaremos el **hook hook_migrate_api()**, el cual nos va a permitir registrar grupos de migraciones distintos (en este ejemplo sólo necesitamos crear un grupo). Este hook es detectado en el archivo *migrate_activities.migrate.inc*, y su contenido se verá generalmente de la siguiente forma: [prism:javascript] /** * Implements hook_migrate_api(). */ function migrate_activities_migrate_api() { $api = array( 'api' => 2, 'groups' => array( 'activities_group' => array( 'title' => t('Activity Migrations'), ), ), 'migrations' => array( 'activities' => array( 'class_name' => 'MigrateActivities', 'group_name' => 'activities_group', ) ), ); return $api; } [/prism:javascript] Este hook retorna la información de los grupos de migraciones, con sus nombres y respectivas clases. Para nuestro caso vamos a necesitar la clase **MigrateActivities**. Esta clase se define en el archivo *activities.inc*, por lo que debemos incluirlo como un file requerido en el archivo *migrate_activities.info* [prism:javascript] files[] = ‘activities.inc’ [/prism:javascript] Es muy importante extender esta clase de un hijo de la clase **Migrate**, por lo que nuestra primera línea de código se verá de esta forma: [prism:javascript] /** * Class MigrateActivities */ class MigrateActivities extends Migration { public function __construct($arguments) { parent::__construct($arguments); } [/prism:javascript] El arreglo de argumentos que se pasa como parámetro al constructor de la clase, incluye el nombre del grupo de la migración y también podemos agregar otros elementos que necesitemos. Antes de continuar, es preciso saber la fuente de datos que queremos migrar. El módulo Migrate nos ofrece un listado interesante con las posibles fuentes que podemos utilizar: [prism:javascript] MigrateSourceSQL MigrateSourceList MigrateSourceMultiItems XML-based sources MigrateSourceCSV JSON-based source classes MigrateSourceMSSQL MigrateSourceOracle HTML and other files as sources MigrateSourceMongoDB [/prism:javascript] Vea https://www.drupal.org/node/1006986. Para este ejemplo, voy a utilizar **MigrateSourceSQL** pues la migración se hará desde una base de datos SQL. **IMPORTANTE:** Se debe crear una conexión a la base de datos que queremos migrar en el archivo settings de drupal, por ejemplo: [prism:javascript] 'migrate_db' => array( 'default' => array( 'database' => 'migrate', 'username' => 'root', 'password' => root, 'host' => 'localhost', 'port' => '', 'driver' => 'mysql', 'prefix' => '', ), ), [/prism:javascript] Con esto, podemos seguir editando la clase *MigrateActivities*. Debajo del constructor colocamos el siguiente código: [prism:javascript] $query = Database::getConnection('default', 'migrate_db') ->select('data', 'a') ->fields('a', array('id', 'title', 'description', 'imageUrl')); $fields = array( 'id' => 'Unique ID for each source data row', 'title' => 'The activity title', 'description' => 'The activity description', 'imageUrl' => 'An image url of the activity' ); $this->source = new MigrateSourceSQL($query, $fields); $this->destination = new MigrateDestinationNode('activities'); [/prism:javascript] Lo que he hecho aquí es decirle a Drupal que establezca una conexión a la base de datos *migrate_db* y haga un select a la tabla data, luego declaro una variable fields donde defino los campos que voy a utilizar de la tabla data y declaro el destino, que en mi caso serán el tipo de contenido activities pues quiero crear nuevos nodos de ese tipo de contenido. El paso siguiente es mapear los datos del source con el destino, para lo cual hacemos lo siguiente: [prism:javascript] $this->map = new MigrateSQLMap($this->machineName, array( 'id' => array( 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, ) ), MigrateDestinationNode::getKeySchema() ); // Mapped fields $this->addFieldMapping('title', 'title') ->description(t('Mapping json object name in source to node title')); $this->addFieldMapping('body', 'description'); $this->addFieldMapping('field_activity_image', 'imageUrl'); [/prism:javascript] El **id** utilizado es el id de la tabla data que he declarado en el **array $fields**, este dato es importante para que Migrate lleve un control de los datos migrados y los que faltan por migrar. A continuación hago el *map* de los campos del tipo de contenido con los campos declarados en el array $fields. Habilitamos nuestro módulo y nos dirigimos a la interfaz de migración en [prism:javascript] admin/content/migrate/configure [/prism:javascript] En esta paǵina hacemos click en el botón **Register statically defined clasess** para registrar nuestra migración gracias al hook_migrate_api(). drupal migrate En el dashboard (admin/content/migrate) se nos muestra algo así: drupal migrate Al hacer click en el nombre del grupo, vemos la tabla de migraciones: drupal migrate En la siguiente imagen se muestra un listado de opciones disponibles para hacer la migración, las cuales están muy bien explicadas. drupal migrate También, si damos click en el título de la tarea, vemos una nueva página que contiene los mapeos que realizamos, y los otros posibles campos disponibles para mapear: drupal migrate Regresamos a la tabla y elegimos la opción de import y esperamos a que el proceso termine. drupal migrate drupal migrate Una vez terminado el proceso, tendremos nuevos nodos de tipo Activities. Como ejemplo, he creado una vista simple para mostrar los resultados de la migración: drupal migrate El módulo de Migrate de Drupal nos brinda la posibilidad de migrar datos desde diferentes tipos de fuentes para crear en nuestro sitio entidades que conocemos, como usarios, nodos, taxonomias, etc. Este módulo nos ahorra muchas horas de trabajo y se hace indispensable en cualquier proyecto donde se necesite hacer una migración de contenidos. Referencia: https://www.drupal.org/migrate