drupal 8 — import csv to d8

reference:

Migration in D8 is bloody suffering. IT SHOULD NOT BE THIS HARD!
Migrations in D8 follow a 3 step process. Gather the data, massage the data, then save the data into a destination.

  1. Gather = Source plugin
  2. Massage = Process plugin
  3. Save = Destination plugin

Here’s a super simple source excerpt:

1
2
3
4
5
6
7
8
9
10
11
source:
plugin: csv
path: public://csv/people.csv
header_row_count: 1
keys:
- id
column_names:
0:
id: Identifier
1:
first_name: First Name

Here’s a simple process excerpt

1
2
3
4
5
process:
type:
plugin: default_value
default_value: people
title: first_name

Here’s the destination excerpt:

1
2
destination:
plugin: entity:node

Migrate Plus Example:

Structure:

  1. Migration configuration, in the config/install directory.
  2. Source plugins, in src/Plugin/migrate/source.

Understand the Migration

Steps:

  1. migrate_plus.migration_group.beer.yml
  2. migrate_plus.migration.beer_term.yml
  3. BeerTerm.php
  4. migrate_plus.migration.beer_user.yml
  5. BeerUser.php
  6. migrate_plus.migration.beer_node.yml
  7. BeerNode.php
  8. migrate_plus.migration.beer-comment.yml
  9. BeerComment.php

migrate_plus.migration_group.beer.yml

1
2
3
4
5
6
7
8
9
10
11
12
id:beer
label:
description:
source_type: Custom tables
shared_configuration:
source:
key:default
dependencies:
enforced:
module:
- migrate_example

migrate_plus.migration.beer_term.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
id: beer_term
label:
migration_group: beer
# Every migration must have a source, which controls the delivery of our source data. In this case, our plugin has the name "beer_term", which Drupal resolves to the PHP class defined in src/Plugin/migrate/source/BeerTerm.php
source:
plugin: beer_term
# Every migration must also have a destination plugin, which handles writting the migrated data in the appropriate form for that particular kind of data. Most Drupal content is an "entity" of one type or another, and we need to specify what entity type we are populating( i n this case, taxonomy terms).
destination:
plugin: entity:taxonomy_term
# describe how each destination field is to be populated based on the source data.
process:
# the simplest process plugin is named 'get' - it is the default so does not need to be explicitly named. It simply copies the source value( the 'style' field from the source database in this case) to the destination field( the taxonomy term 'name' field). We also simply copy the source 'details' field to destination 'description' field in the same way.
name: style
description: details
# default_value plugin is used to hard-code a destination value, the vid (vocabulary ID) our taxonomy terms should be assigned to. It's important to note that above the right side of the mappings was a source field name, here the right side of the 'default_value' line is an actual value.
vid:
plugin: default_value
default_value: migrate_example_beer_styles
# The migration frameworks keeps tracks of the relationships between source and destination IDs in map tables, and the migration plugin is the means of performing a lookup in those map tables during precessing.
parent:
plugin: migration
migration: beer_term
source: style_parent
migration_dependencies: {}
dependencies:
enforced:
module:
- migrate_example

migrate_plus.migration.beer_node.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
id: beer_node
loable:
migration_group: beer
source:
plugin: beer_node
destination:
plugin: entity:node
process:
type:
plugin: default_value
default_value: migrate_example_beer
title:name
nid: bid:
uid: migration
migration: beer_user
source: aid
sticky:
plugin: default_value
default_value: 0
field_migrate_example_country:countries
field_migrate_example_beer_style:
plugin: migration
migration: beer_term
source: terms
# Some Drupal fields may have multiple components we may want ot set separately. For example, text fields may have summaries (teasers) in addition to the full text value. We use / to separate the field name form the internal field value being set, and put it in quotes because / is a YAML special character
'body/value': body
'body/summery: excerpt
migration_dependencies:
required:
- beer_term
- beer_user
dependencies:
enforced:
module:
- migrate_example

Running the migrations

drush en -y migrate_tools,migrate_example

drush ms

drush mi –group=beer

My yml so far

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
uuid: ee61edfb-bc0e-41ef-8907-885d7c28e040
langcode: en
status: true
dependencies: { }
id: new_test
migration_tags: null
migration_group: null
label: 'Import analyses'
source:
plugin: csv
path: /var/www/html/drupal/basic.csv
header_row_count: 1
keys:
- Id2
process:
title: title
body: body
field_start_date: date
field_label:
plugin: entity_generate
source: label
field_category:
plugin: entity_generate
source: category
type:
plugin: default_value
default_value: analyses
destination:
plugin: 'entity:node'
migration_dependencies: null

plugin: entity_generate is used to create taxonomy if it doesn’t exist. At least it works