Skip to main content

How to Migrate CSV to Node in Drupal (Migrate Source CSV)

1. To add a migrate from csv file feature in your Drupal site, you need three modules

Migrate Source CSV 
https://www.drupal.org/project/migrate_source_csv

Migrate Plus 
https://www.drupal.org/project/migrate_plus

Migrate Tools
https://www.drupal.org/project/migrate_tools

2. Install migrate_source_csv, migrate_plus and migrate_tools using composer commands from their respective project pages like:


#install modules
composer require 'drupal/migrate_source_csv:^3.6'
composer require 'drupal/migrate_plus:^6.0'
composer require 'drupal/migrate_tools:^6.0'


#enable modules
vendor/bin/drush en migrate_source_csv
vendor/bin/drush en migrate_plus
vendor/bin/drush en migrate_tools


#clear cache
vendor/bin/drush cr

3. Go to admin/config/development/configuration/single/import


YAML File – Structure (You have to paste the below code – starting from id in the YAML section)
********************
id: <unique_name_id>
label: Import Salaries
migration_group: default
type: content_type
source:
 plugin: 'csv'
 # Full path to the file.
 path: 'public://<folder in sites/default/files>/file_with_data.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.

 ids:
   - title  
 fields:
   0:
     name: title
     label: 'Title'
   1:
     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: <content_type_of_your_node_machine_name>
destination:
 plugin: entity:node


5. Select Configuration Type -> Migration

6. Copy Paste the YAML Structure from 4 to the Text Area in admin/config/development/configuration/single/import

7. Click IMPORT

8. One big challenge you are likely to face is setting the source path of the csv files.

The easiest route is to add a folder in the public file system

sites/default/files/< name_for_csv_import_folder>/data1.csv
then in your csv the source path would be public://<name_for_csv_import_folder>/data1.csv

source:
 plugin: 'csv'
 # Full path to the file.
 path: 'public://<name_for_csv_import_folder>/data1.csv'
source:
 plugin: 'csv'
 # Full path to the file.
 path: 'public://<name_for_csv_import_folder>/data1.csv'

9. After pressing the IMPORT button and if you don't see any error - the nodes won't be created automatically

10. Run Drush. You have to run a drush command

drush migrate-import <id>

<id> is <unique_name_id>from 4

vendor/bin/drush migrate-import <unique_name_id>

Common Errors and Challenges

1. Id has no Value

Migration failed with source plugin exception:  is defined as a source ID but has no value. 
Comment out id from
# 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
Replace with the first column of your csv file. It might not be id. For us it was the title of the node so the entry for us was:
 ids:
   - title  
 fields:
   0:
     name: title
     label: 'Title'
   1:
     name: post_body
     label: 'Post body'

2. Phantom Fields

If you have phantom config fields - from the previous migration or uninstallation, you will not be able to import the CSV and get an error like:

The configuration cannot be imported because it failed validation for the following reasons:

Configuration <name>.settings depends on the <name> extension that will not be installed after import.
Configuration <name1>.default depends on the field.field.node.<module_name> configuration that will not exist after import.

vendor/bin/drush config-delete <name>.settings
vendor/bin/drush config-delete <name1>.default

3. Adding Path Alias
For that you must first add a constants variable in the source section like this
constants:
   slash: '/'

Then define and map the path variable in the process: section like this
path:
   plugin: concat
   source:
     - constants/slash
     - path

What it does is that the node url alias will start with constants/slash value. In this case "/" then it will search for "path" column from the csv file

4. Add Default author under whose name the node will be published

process:
 title: title
 body: post_body
 type:
   plugin: default_value
   default_value: salary
 path:
   plugin: concat
   source:
     - constants/slash
     - path
 uid:
   plugin: default_value
   default_value: 4

Add a uid in the process section with a default_value. In our case user 4 was the author for all imports from csv to the node.

Note: A user with userid 4 should exist. You can see the userid while editing the username in the People section of Drupal Admin. See the url.
 

Drupal