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.
Gather = Source plugin
Massage = Process plugin
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:
Migration configuration, in the config/install directory.
Source plugins, in src/Plugin/migrate/source.
Understand the Migration
Steps:
migrate_plus.migration_group.beer.yml
migrate_plus.migration.beer_term.yml
BeerTerm.php
migrate_plus.migration.beer_user.yml
BeerUser.php
migrate_plus.migration.beer_node.yml
BeerNode.php
migrate_plus.migration.beer-comment.yml
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