How to Migrate Images into Drupal 8 Using CSV Source

Posted by Ada Hernández on October 25, 2016
Development
Migration & Upgrades
Strategy & Architecture
Support

In this post, I'll show you how to migrate a csv file that contains a photo, and how do it do it using Migrate Source CSV module. 

The Migrate Source CSV module provides a source plugin called "csv" for using  .csv files as a migration source.

For our migration we have a .csv file with random data you want to migrate into Drupal 8:

filecsv

Drupal provides us with a wide range of field types, such as integer, date, image, file, string or email, which are provided by the Drupal core. But there are also other types of fields such as that provided by media entity module or paragraphs. Each of these have their own entity reference fields.

We need the following modules for our migration:

and have drush or drupal console installed.

First we create the content type(s) that our migration data will eventually get stored into and the various fields on each of those content types.

Content type: Profile

Fields:

First name Text(Plain)
Last name Text(Plain)
Birthday Date
Email Email
Photo Image
Language Taxonomy term

Then we create our custom modulecustom_migrate and in the custom_migrate.info.yml we put :

name: My first migration
description: With this module I will migrate a csv file.
type: module
core: 8.x
package: Migration
dependencies:
  - migrate
  - migrate_plus
  - migrate_source_csv
  - migrate_tools
  - node

After that, we create the the directory config/install and inside that we put our migration template called: migrate_plus.migration.profile.yml

dependencies:
  module:
    - migrate_source_csv
id: profile
migration_tags:
  - CSV
migration_group: null
label: Profile
source:
  plugin: csv
  path: modules/custom/custom_migrate/assets/csv/profile.csv
  header_row_count: 1
  keys:
    - id
  column_names:
    -
      id: ID
    -
      first_name: 'First Name'
    -
      last_name: 'Last Name'
    -
      birthday: Birthday
    -
      email: Email
    -
      photo: Photo
    -
      languages: Language
process:
  type:
    plugin: default_value
    default_value: profile
  title:
    plugin: concat
    source:
      - first_name
      - last_name
    delimiter: ' '
  field_first_name: first_name
  field_last_name: last_name
  field_birthday: birthday
  field_email: email
  field_language:
    plugin: entity_generate
    source: languages
  field_photo:
    -
      plugin: explode
      source: photo
      delimiter: ;
    -
      plugin: callback
      callable: trim
    -
      plugin: callback
      callable: strtoupper
    -
      plugin: migration
      migration: photo
      no_stub: true
destination:
  plugin: 'entity:node'
migration_dependencies:
  optional:
    - photo

We have the Id of the migration: this should be unique, migration_tags:  a tag to filter the migrations when we are running them, migration_group: the migration group where we can assign common configuration to each member of the group.

Source: In the plugin source we specify the plugin configuration for the source data.

Process: Here we map the source to the destination fields

Destination: This is the destination entity where the data is destined.

You can consult the migration API documentation.

As shown in our profile template below, the destination has a field_photo image file type. For this we use the following template:

File called: migrate_plus.migration.photo.yml


dependencies:
  module:
    - file
id: photo
migration_tags:
  - CSV
migration_group: null
label: Photos
source:
  constants:
    source_base_path: modules/custom/custom_migrate/assets/photos
    uri_file: 'public://photos'
  plugin: csv
  track_changes: true
  path: modules/custom/custom_migrate/assets/csv/profile.csv
  header_row_count: 1
  keys:
    - name
  column_names:
    5:
      name: Photo

process:
  source_full_path:
    -
      plugin: concat
      delimiter: /
      source:
        - constants/source_base_path
        - name
    -
      plugin: urlencode
  uri_file:
    -
      plugin: concat
      delimiter: /
      source:
        - constants/uri_file
        - name
    -
      plugin: urlencode
  filename: name
  uri:
    plugin: file_copy
    source:
      - '@source_full_path'
      - '@uri_file'
destination:
  plugin: 'entity:file'
migration_dependencies:
  required: {  }
  optional: {  }

We declared 2 constants in the source with the path to the files in their source and the destination i.e if  we want to store our files in sites/default/files/photos, we use public://photos.

Then we enable the custom module along with its dependencies to install our custom migration configuration.

and run drush cex to run our new migrations.

Using this type of method, it is easy to migrate basic profile data for a person, even their photo.

To see the state of our migration we use drush:

drush ms

To import a single migration drush mi <name> and to rollback (delete) we run drush mr

Also we can use drupal console to import any modifications we made to our various yaml files.

drupal config:import:single [arguments]

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.


How to Migrate Images into Drupal 8 Using CSV Source