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.