0

I am migrating content that contains paragraphs also. So I have two migration files.

When the content is migrated. Everything is fine. I can see the paragraphs are attached with the nodes.

When I edit a migrated node and adds a new paragraph to the node, then when I execute the migration again, that new paragraph removes from that node. Is there any way to keep them?

The paragraph_import.yml

langcode: en
status: true
id: paragraph_import
label: My paragraph import
migration_tags:
  - paragraph
source:
  plugin: csv
  delimiter: ','
  enclosure: '"'
  escape: '`'
  header_offset: 0
  ids: ['personal_number']
destination:
  plugin: 'entity_reference_revisions:paragraph'
  default_bundle: my_paragraph
process:
  mail:
    - plugin: skip_on_empty
      method: process
      source: 'e-mail werk'
  cellphone:
    - plugin: skip_on_empty
      method: process
      source: 'gsm werk'
  phone:
    - plugin: skip_on_empty
      method: process
      source: telefoon
  langcode:
    - plugin: default_value
      default_value: 'nl'
dependencies:
  enforced:
    module:
      - migrate_source_csv

The node migration.

langcode: en
status: true
id: contact_import
label: Contacts
migration_tags:
  - node
source:
  plugin: csv
  delimiter: ','
  enclosure: '"'
  escape: '`'
  header_offset: 0
  ids: ['personal_number']
destination:
  plugin: 'entity:node'
  default_bundle: contact
process:
  type:
    plugin: default_value
    default_value: contact
  title: title
  paragraph:
    - plugin: migration_lookup
      migration: paragraph_import
      source: personal_number
  my_paragraph_field:
    - plugin: sub_process
      source:
        - '@paragraph'
      process:
        target_id: '0'
        target_revision_id: '1'
  langcode:
    - plugin: default_value
      default_value: 'nl'
dependencies:
  enforced:
    module:
      - migrate_source_csv

My migration execute code.

$migration = $this->migrationPluginManager->createInstance($migration_id);
$migration->getIdMap()->prepareUpdate();
 try {
   $executable = new MigrateExecutable($migration, new MigrateMessage());
   $executable->import();
 }
 catch (MigrateException $exception) {
   $this->logger->error($exception->getMessage());
 }

It is different from this question Because that question talks about the fields in the paragraph. While this question is about the paragraph entity itself.

4
  • Isn't this the same question as How to preserve the values of paragraph fields in migration??
    – Hudri
    Mar 25, 2021 at 8:36
  • That question was about the fields in the paragraph. This question is about the pargraph itself.
    – Ahmad
    Mar 25, 2021 at 8:39
  • This is because you are overwriting/wiping the paragraph deltas most likely. This is moving a paragraph from A to B, its not preserving anything. I doubt there is a simple way to do that. A general rule of thumb is you cannot migrate content/data while also manually editing the same destinations.
    – Kevin
    Mar 25, 2021 at 13:19
  • @Kevin this makes sense. So if you are migrating content you cannot add it manually
    – Ahmad
    Mar 25, 2021 at 13:34

1 Answer 1

0

I have created a custom source plugin for this to achieve.

Here is my source plugin code.

class MYSOURCECSV extends CSV {

  /**
   * {@inheritdoc}
   */
  public function prepareRow(Row $row) {
    $database = \Drupal::database();
    $table = 'migrate_map_migration_id';

    // The migration removes the manually created entities from the system,
    // that are not present in the migration source. But we want them to be
    // ignored during the migration.
    if ($database->schema()->tableExists($table)) {
      $organisations = [];

      try {
        $results = $database->select($table, 'mmt')
          ->fields('mmt', ['destid1', 'destid2'])
          ->condition('sourceid1', $row->getSourceProperty('personal_number'))
          ->execute()
          ->fetchAll();

        if (!empty($results)) {
          foreach ($results as $result) {
            $paragraph_id = $result->destid1;

            $paragraph = \Drupal::entityTypeManager()
        

  ->getStorage('paragraph')
          ->load($paragraph_id);

        if ($paragraph instanceof ParagraphInterface) {
          $node = $paragraph->getParentEntity();

          // If paragraph is already attached to a node. Get the ids from
          // the node.
          if ($node instanceof NodeInterface) {
            $organisations = $node->get('my_paragraph_field')->getValue();

            if ($key = array_search($paragraph_id, array_column($paragraphs, 'target_id'))) {
              $paragraphs[$key]['target_revision_id'] = $result->destid2;
            }
          }
          else {
            $paragraphs[] = [
              'target_id' => $result->destid1,
              'target_revision_id' => $result->destid2,
            ];
          }
        }
      }
    }

    $row->setSourceProperty('my_paragraph_field', $paragraphs);
  }
  catch (Exception $exception) {
    \Drupal::logger('my_module')->error($exception->getMessage());
  }
}

parent::prepareRow($row);
  }

}

And then change the paragraph field mapping in the migration file to:

my_paragraph_field:
    - plugin: sub_process
      source: organisations
      process:
        target_id: target_id
        target_revision_id: target_revision_id

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.