I'm doing a D7 to D8 custom migration. In Drupal 7, I have a multi-value formatted text field that I am trying to map to a Drupal 8 multi-value Paragraph entity reference field.

I've separated this into two migrations. One for the paragraphs, and one for the nodes themselves. I've got the multi-value field to paragraph migration working (although I think there might be an issue with the way that I have done the IDs). I have the node migration working as well, with the exception that none of the references to the already migrated paragraph entities are being migrated.

I realize that right now, this seems unnecessary, but it's part of a feature upgrade.

Below is the code from my migration classes/plugins.

This is from migrate_plus.migration.presentation_node.yml. Field_slide is the paragraph reference field.

  plugin: migration
  migration: presentation_slide
  source: entity_id

This is the getIds function from PresentationSlide.php. This is the plugin for the paragraph migration.

public function getIds() {
  return [
    'entity_id' => [
      'type' => 'integer',
      'alias' => 'lt',

This is also from PresentationSlide.php. Here I am combining the entity_id and delta to form a unique id. I realize that this is a terrible way to do this, but I couldn't figure out anything better. Any tips on this are welcome.

public function prepareRow(Row $row) {
  $nid = $row->getSourceProperty('entity_id');
  $delta = $row->getSourceProperty('delta');
  $slide_id = (string) $nid . (string) $delta;
  $slide_id = (int) $slide_id;
  $row->setSourceProperty('entity_id', $slide_id);

  return parent::prepareRow($row);

And this is from PresentationNode.php. Here I am fetching all of the referenced fields, and passing that as an array to the migration class.

public function prepareRow(Row $row) {
  $nid = $row->getSourceProperty('nid');
  $query = $this->select('field_data_field_learning_text', 'lt')
    ->condition('entity_id', $nid);
  $query->addExpression('CONCAT(entity_id, delta)', 'target_id');

  $slides = $query->execute()->fetchCol(); 

  if (!empty($slides)) {
    $row->setSourceProperty('entity_id', $slides);

  return parent::prepareRow($row);

The main issue here is that I can't figure out how to properly use a multiple column key. It seems to me that all of my issues are due to my doing this improperly.

Thanks in advance. I realize this is a lot.


Thanks Berdir for the help. I've taken a stab at implementing your processing plugin. However, I'm having an issue where the migration seems to be skipping right over and ignoring the process plugin.

  plugin: paragraph_process_base
  source: field_body_value

Feel like there is something super simple that I'm missing here.

[Edit 2] And I had a typo... Thanks a ton!

2 Answers 2


This is not directly an answer, but it is also too long for a comment :)

When I migrated something that wasn't actually paragraphs into paragraphs, I just wrote a custom process plugin that created paragraphs on the fly, then I didn't have to bother about trying to figure out some kind of mapping/made up ID's. What you're doing definitely seems like a bad idea, as 1010 could either be delta 10 from node 10 or delta 0 from node 101.

Put two classes I used for that into a gist: https://gist.github.com/Berdir/8a650a29a670fe283589f8946354086c.

It is both a bit hacky and a fairly complicated as I needed to support importing multiple translations for separate nodes in 6.x to a single node with a single paragraph with translations in 8.x.

Also created a to-do for me to write a blog post about this. ;)

  • It's super hacky for sure. Although all of my nodes are in the 600-900 range, so I know for sure I won't have that sort of overlap with my set of data. You aren't wrong though!
    – lukedekker
    Commented Dec 22, 2016 at 23:01
  • 2
    Your knowledge of basically most systems of Drupal 8 never stops to amaze me.
    – Kevin
    Commented Dec 23, 2016 at 17:50
  • Thanks, I guess ;) That is probably related to the fact that I am working on/maintaing a probably unhealthy amount of core components and contrib modules and I'm good at remembering stuff ;)
    – Berdir
    Commented Dec 23, 2016 at 21:37
  • This is wonderfully helpful to me, thankyou! Commented Feb 1, 2017 at 5:14
  • Hi Berdir, could you give feedback on the note in the answer by @Pasqualle? "While this method can work, it's no longer recommended for Entity Reference Revisions 1.2 or higher."
    – mpp
    Commented Feb 16, 2018 at 10:57

Related blog post: https://deninet.com/blog/2017/06/18/building-custom-migration-drupal-8-part-5-paragraphs

There is a very popular post on Stack Overflow that suggests you write a custom process plugin. While this method can work, it's no longer recommended for Entity Reference Revisions 1.2 or higher.

Drupal.org handbook page would be really useful now..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.