Migración de datos CSV a párrafos

Publicado por el 7 de Diciembre de 2016

Con el trabajo cotidiano de la oficina es natural que en el desarrollo de tareas se presenten desafíos y potenciales temas de investigación. Con la incorporación de nuestro desarrollador Lucas, al grupo de mantenedores del core del sistema de migraciones hemos decidido adentrarnos en este tema poco documentado como es la migración de datos CSV a párrafos.

Párrafos es la nueva forma de creación de contenido. Le permite a los constructores de sitios hacer las cosas más limpias para que pueda dar más poder de edición a sus usuarios finales.

En este blog les explicaré de forma sencilla cómo migrar datos de CSV a párrafos, usando el escenario de un tipo de contenido de Landing Page que tiene un campo de banner (párrafo de valor único) y un campo de Tile (campo de párrafos con varios valores). Asi que el blog abarca los 2 temas muy bien.

Veamos primero nuestros dos archivos CSV. La primer línea de los archivos es la fila del encabezado. Seguido por filas de los valores del CSV. Todo muy normal hasta ahora.

# files.csv
banner
banner.jpg
img1.jpg
img2.jpg
img3.jpg

 

# landing_pages.csv
id,title,banner_image,banner_link,banner_link_text,desc1,img1,desc2,img2,desc3,img3
1,Services,banner.jpg,http://www.mtech-llc.com,"Go to site",Desc1,img1.jpg,Desc2,img2.jpg,Desc3,img3.jpg

Paragraphs Type: Banner

A continuación debemos construir nuestros tipos de párrafo. El tipo de párrafo banner tiene dos campos. Esto debería parecer muy familiar si alguna vez ha tratado con párrafos o construyendo un sitio de Drupal.

Field Name Field Type
Call to Action Link
Image Image

Paragraphs Type: Tile

Este tipo de párrafo Tile también tiene dos campos y permite imprimir texto con un campo de imagen asociado. El autor de Landing Page va a construir un conjunto bien estructurado de tiles para la región de contenido principal de Landing Page. Por supuesto, puedes intercambiar estos campos y hacer tus párrafos como quieras. Pero esto sólo le da algunos tipos de párrafos muy típicos y enfoques de migración.

Field Name Field Type
Description Text (formatted, long)
Image Image

Y luego creamos el tipo de contenido y sus campos con referencia a párrafos:

Content Type: Landing Page

Field Name Field Type
Banner Entity reference revisions (paragraph field)
Tile Entity reference revisions (multi-valor paragraph field)

En este punto, estamos listos para migrar datos, necesitaremos descargar y habilitar con drush los módulos de contribución Entity Reference Revisions (en este aplicaremos el patch Entity Reference Revisions migrate destination), Migrate Plus, Migrate Source CSV, Migrate Tools y Paragraphs). Con Drupal Console crearemos nuestro módulo personalizado y lo he llamado paragraph_migration( con dependecias migrate_plus, migrate_source_csv y migrate_tools). Para mayor comodidad de este ejemplo, dentro de este módulo estarán los archivos .csv creados (files.csv y landing_pages.csv) con la siguiente ruta paragraph_migration/assets/csv, así mismo las imágenes .jpg dentro de la ruta paragraph_migration/assets/img. Por último, almacenarlos yaml de migración dentro del módulo paragraph_migration en la ruta paragraph_migration/config/install. 

Empecemos:

En el sitio, estos archivos se muestran en  /admin/content/files.

dependencies:
  enforced:
    module:
      - paragraph_migration
id: files
source:
  plugin: csv
  path: modules/custom/paragraph_migration/assets/csv/files.csv
  header_row_count: 1
  keys:
    - name
  constants:
    source_base_path: modules/custom/paragraph_migration/assets/img
    destination_base_path: 'public:/'
process:
  filename: name
  source_full_path:
    -
      plugin: concat
      delimiter: /
      source:
        - constants/source_base_path
        - name
    -
      plugin: urlencode
  destination_full_path:
    -
      plugin: concat
      delimiter: /
      source:
        - constants/destination_base_path
        - name
    -
      plugin: urlencode
  uri:
    plugin: file_copy
    source:
      - '@source_full_path'
      - '@destination_full_path'
destination:
  plugin: 'entity:file'
migration_dependencies:
  required: { }
  optional: { }
  • Migración de párrafo mulltivalor de  -banner, tile_1, tile_2, tile_3-: Usaremos el plugin de destino proveído por el módulo Entity Reference Revisions 'entity_reference_revisions:paragraph' **Es muy importante que dicho plugin sea en singular, diferente al nombre del módulo, para evitar errores a la hora de la migración**
dependencies:
  enforced:
    module:
      - paragraph_migration
id: banner
source:
  plugin: csv
  path: modules/custom/paragraph_migration/assets/csv/landing_pages.csv
  header_row_count: 1
  keys:
    - id
process:
  field_image:
    plugin: migration
    migration: files
    source: banner_image
    no_stub: true
  field_call_to_action/title: banner_link_text
  field_call_to_action/uri: banner_link
destination:
  plugin: 'entity_reference_revisions:paragraph'
  default_bundle: banner
migration_dependencies:
  required:
    - files
  optional: { }
dependencies:
  enforced:
    module:
      - paragraph_migration
id: tile_1
source:
  plugin: csv
  path: modules/custom/paragraph_migration/assets/csv/landing_pages.csv
  header_row_count: 1
  keys:
    - id
    - img1
process:
  field_image:
    plugin: migration
    migration: files
    source: img1
    no_stub: true
  field_description: desc1
destination:
  plugin: 'entity_reference_revisions:paragraph'
  default_bundle: tile
migration_dependencies:
  required:
    - files
  optional: { }
dependencies:
  enforced:
    module:
      - paragraph_migration
id: tile_2
source:
  plugin: csv
  path: modules/custom/paragraph_migration/assets/csv/landing_pages.csv
  header_row_count: 1
  keys:
    - id
    - img2
process:
  field_image:
    plugin: migration
    migration: files
    source: img2
    no_stub: true
  field_description: desc2
destination:
  plugin: 'entity_reference_revisions:paragraph'
  default_bundle: tile
migration_dependencies:
  required:
    - files
  optional: { }
dependencies:
  enforced:
    module:
      - paragraph_migration
id: tile_3
source:
  plugin: csv
  path: modules/custom/paragraph_migration/assets/csv/landing_pages.csv
  header_row_count: 1
  keys:
    - id
    - img3
process:
  field_image:
    plugin: migration
    migration: files
    source: img3
    no_stub: true
  field_description: desc3
destination:
  plugin: 'entity_reference_revisions:paragraph'
  default_bundle: tile
migration_dependencies:
  required:
    - files
  optional: { }

** Para cada archivo de migración YML de tiles es necesario agregar el id y el nombre de la imagen como id o clave para la migración. **

  • Destino de nuestra migración: Por último vamos a revisar el archivo YML que debe reunir nuestras migraciones anteriores en Paragaphs. Hay un enfoque diferente utilizado para los párrafos de múltiples valores en comparación con los párrafos de valor único, así que presta mucha atención a los detalles.
dependencies:
  enforced:
    module:
      - paragraph_migration
id: landing_pages
source:
  plugin: csv
  path: modules/custom/paragraph_migration/assets/csv/landing_pages.csv
  header_row_count: 1
  keys:
    - id
process:
  title: title
  field_banner/target_id:
    -
      plugin: migration
      migration: banner
      no_stub: true
      source: id
    -
      plugin: extract
      index:
        - '0'
  field_banner/target_revision_id:
    -
      plugin: migration
      migration: banner
      no_stub: true
      source: id
    -
      plugin: extract
      index:
        - 1
  combination_1:
    plugin: get
    source:
      - id
      - img1
  combination_2:
    plugin: get
    source:
      - id
      - img2
  combination_3:
    plugin: get
    source:
      - id
      - img3
  combination:
    plugin: get
    source:
      - @combination_1
      - @combination_2
      - @combination_3
  field_tile:
    -
      plugin: migration
      migration:
        - tile_1
        - tile_2
        - tile_3
      no_stub: true
      source: @combination
    -
      plugin: iterator
      process:
        target_id: '0'
        target_revision_id: '1'
destination:
  plugin: 'entity:node'
  default_bundle: landing_page
migration_dependencies:
  required:
    - banner
    - tile_1
    - tile_2
    - tile_3
  optional: { }

**field_banner/target_id y field_banner/target_id : El valor del extract '0' (con comillas simples) es importante y no es un error. Si no lo haces de esta manera,el plugin de proceso extract tratará cero como vacío y omitirá extraer el valor. El valor de 1 (sin comillas) está bien para el plugin de extract. No omite el valor numérico de uno.

**combination: Se trata de un campo temporal o psuedo -campo que se utiliza para recopilar todos los valores fuente juntos, en el formato correcto para insertar posteriormente en el destino real. Se puede decir que es un campo temporal porque tiene un nombre  aleatorio que no comienza con el prefijo 'field_' y más tarde se utiliza con un prefijo de signo (@). Utilizamos el campo de combination como intermediario para el destino final 'field_tile'.

En la segunda parte de migración de párrafo multivalor, el plugin iterador sólo acepta valores de strings. No le gustan los números. Las comillas simples alrededor de '0' y '1' no son un error. Esto es diferente a lo que se menciona anteriormente de field_banner/target_id y field_banner/target_id.

Con nuestros yamls de migración totalmente respaldados y nuestros tipos de contenido creados, ahora es el momento de ver cómo funciona. Procedemos a habilitar el módulo paragraphs_migration ya que los archivos están forzados a su dependencia:

$ drush en paragraph_migration -y

Corremos la migración:

$ drush mi --all

LISTO!!!

Puedes obtener el código de este blog en mi repositorio en GitHub.

¿Está buscando ayuda para una migración o actualización de Drupal? Independientemente de la complejidad del sitio o de los datos, MTech puede ayudarle a pasar de un CMS privado o actualizarlo a la última versión: Drupal 8.

Escríbanos sobre su proyecto y nos pondremos en contacto con usted dentro de 48 horas.