Ultimate guide to migrating data into Drupal 8

Posted by Charlotte León on April 20, 2017

MTech specializes in Drupal migrations and upgrades. MTech owner and lead architect, Lucas Hedding, is a Drupal Core migration system maintainer and will be presenting on Drupal Migrations this Wednesday at DrupalCon Baltimore.

The scenerio we will use in this post is some profile data for a person. Their first and last name, date of birth, country of residence, email address and a headshot. With this type of data, we have a nice mixture of souce data that includes term data, dates and some images.

Country of residence is a taxonomy term or entity reference field. We migrate that using entity_generate process plugin from the migrate_plus contrib module. For more details on a simple method to migrate simple term data, see Entity Lookup & Generate migrate process plugins.

Date of birth is a date field. A process plugin for this just got accepted into 8.3.x. For more details on how to migrate into date and date_range fields, see Migrating Date Ranges from CSV into Date Range Module.

The profile photo is an image migration. For more details on how to migrate images, see How to Migrate Images into Drupal 8 Using CSV Source.

And lastly, we don't include it in this example data model, but you can even get complicated and migrate data into Paragraph fields. For that, see Migration of CSV Data into Paragraphs

And finally, here's a quick review of how the entire Drupal migration system works, in a nut-shell. The basic structure of a content migration has three main points: Source, Process, and Destination.

  • Source: Here you specify the plugin where the migration will gather the data.
source:
  plugin: csv
  path: modules/custom/custom_migrate/assets/csv/file.csv
  • Process: This section describes, property by property, how the destination is to be constructed from the source data. The value of the process key is an associative array, where each key is a target property. The values associated with each key describe how to create the target value. Most fields can be mapped directly; we just specify the destination without any data transformation.
field_first_name: first_name
  • Destination: Here the processed data (adjusted and manipulated) is stored or saved into a destination. Destination always is a required plug-in.

A simple example:

destination:
  plugin: 'entity:node'

 

A full demo migration project is in our git repository. But if you don't want to head over there, here's a full copy of the simplified entire "process". Pun intended.

#migrate_plus.migration.person_csv.yml
dependencies:
  enforced:
    module:
      - custom_migrate
id: person_csv
label: Person csv migration
migration_tags:
  - CSV
source:
  plugin: csv
  path: /artifacts/people.csv
  header_row_count: 1
  keys:
    - id
  column_names:
    0:
      id: Identifier
    1:
      first_name: First Name
    2:
      last_name: Last Name
    3:
      email: Email Address
    4:
      country: Country
    5:
      ip_address: IP Address
    6:
      date_of_birth: Date of Birth
    7:
      filename: Profile photo
process:
  type:
    plugin: default_value
    default_value: person
  title:
    -
      plugin: concat
      source:
        - first_name
        - last_name
      delimiter: ' '
    -
      plugin: substr
      length: 255
  field_first_name:
    plugin: substr
    length: 60
    source: first_name
  field_last_name:
    plugin: substr
    length: 60
    source: last_name
  field_email: email
  field_country:
    plugin: entity_generate
    source: country
  field_ip_address:
    plugin: substr
    length: 16
    source: ip_address
  field_date_of_birth:
    plugin: format_date
    from_format: 'm/d/Y'
    to_format: 'Y-m-d'
    source: date_of_birth
  field_image/target_id:
    plugin: migration
    migration: person_file_csv
    source: filename
  field_image/alt:
      plugin: concat
      source:
        - first_name
        - last_name
      delimiter: ' '
destination:
  plugin: entity:node
migration_dependencies:
  required:
    - person_file_csv
  optional: {}
#migrate_plus.migration.person_csv.yml
dependencies:
  enforced:
    module:
      - custom_migrate
id: person_file_csv
label: Person file csv migration
migration_tags:
  - CSV
source:
  plugin: csv
  path: /artifacts/people.csv
  header_row_count: 1
  keys:
    - filename
  column_names:
    7:
      filename: Profile photo
  constants:
    source_base_path: /artifacts/photos
    destination: 'public://photos'
process:
  source_full_path:
    -
      plugin: concat
      delimiter: /
      source:
        - constants/source_base_path
        - filename
    -
      plugin: urlencode
  destination:
    -
      plugin: concat
      delimiter: /
      source:
        - constants/destination
        - filename
    -
      plugin: urlencode
  filename: filename
  uri:
    plugin: file_copy
    source:
      - '@source_full_path'
      - '@destination'
destination:
  plugin: entity:file
migration_dependencies:
  required: {}
  optional: {}

If you are at DrupalCon this week, check out the Migrate with the Maintainer's Lab on Wednesday and ask Lucas any questions you have about the guide. He is always very friendly and likes to help.

 

Are you looking for help with a Drupal migration or upgrade? Regardless of the site or data complexity, MTech can help you move from a proprietary CMS or upgrade to the latest version–Drupal 8.

Write us about your project, and we’ll get back to you within 48 hours.