Migrating data from a CSV source

Last updated on
5 January 2024

The contributed Migrate Source CSV module provides a source plugin for utilizing .csv files as migration sources.

A more complete example module called migrate_source_csv_test can be found in the migrate_source_csv/tests/modules folder.

How to import a simple CSV file with Migrate Source CSV plugin

This very basic example will show you how to import Title and Body into the Article content type from a CSV file. The CSV source plugin can also be used to migrate any kind of entities to Drupal, refer to the examples on migrating other entity types.

  1. Download Migrate Source CSV and enable it.
  2. Download Migrate Plus and enable it
  3. Download Migrate Tools and enable it.
  4. Ensure you're using the latest version of Drush.
  5. Create a sample CSV-file called articles.csv with the following content. The delimiter can be configured in the migration definition.
    id,title,post_body
    1,title 1,some body text 1
    2,title 2,some body text 2
    3,title 3,some body text 3
  6. The contributed Migrate Plus module allows migration plugins to be implemented as configuration entities, allowing them to flexibly be loaded, modified, and saved.
    • Navigate to Administration > Configuration > Development > Synchronize (admin/config/development/configuration/single/import)
    • select Migration as the Configuration type
    • Copy-paste the YAML format migration definition and click Import. Note that the path to the CSV file is defined in the configuration. The path is from the Drupal root, and could be for example modules/custom/my_migration/companies.csv or ../assets/companies.csv.
uuid: 1bcec3e7-0a49-4473-87a2-6dca09b91aba
id: article_csv_import
label: Import articles
migration_group: default

source:
  plugin: 'csv'
  # Full path to the file.
  path: '/path/to/articles.csv'
  # Column delimiter. Comma (,) by default.
  delimiter: ','
  # Field enclosure. Double quotation marks (") by default.
  enclosure: '"'
  # The row to be used as the CSV header (indexed from 0), 
  # or null if there is no header row.
  header_offset: 0
  # The column(s) to use as a key. Each column specified will 
  # create an index in the migration table and too many columns 
  # may throw an index size error.
  ids:
    - id
  # Here we identify the columns of interest in the source file. 
  # Each numeric key is the 0-based index of the column. 
  # For each column, the key below is the field name assigned to 
  # the data on import, to be used in field mappings below. 
  # The label value is a user-friendly string for display by the 
  # migration UI.
  fields:
    0:
      name: id
      label: 'Unique Id'
    1:
      name: title
      label: 'Title'
    2:
      name: post_body
      label: 'Post body'

# The order is Drupal field first, and then source field
process:
  title: title
  body: post_body
  type:
    plugin: default_value
    default_value: article

destination:
  plugin: entity:node

Executing the migration

The contributed Migrate Tools provides 'migrate-import' Drush command that you can execute on the command line of our server:

Files path with Migrate Files (extended) Module

For a local directory, you should be able to make the path in the CSV the absolute local path (e.g. /Users/username/Documents/WebsiteImages on OSX or if you're on Windows C:\Users\username\Documents\WebsiteImages).

Otherwise, another thing you could do is put the files somewhere in your local website's public files directory (i.e. sites/default/files), then your paths in the CSV can use the public:// stream wrapper to reference the files. So for example, let's say you wanted to import a file named document.pdf. You could put that file in sites/default/files/import-sources/document.pdf, and then in your csv the source path would be public://import-sources/document.pdf.

Help improve this page

Page status: No known problems

You can: