Some people want to have the best of both worlds, they want their Migrations to both create new entities, rollback entities, and keep some or all of the customized values on their drupal site. Lots of documentation out there on how to Updating existing content rather than importing new content. This is a system-of-record choice and has a lot of drawbacks, namely you can't add new entities and you can't rollback the entire set.

One way to have your cake and eat it to, is to "protect" certain fields on default "replace all the things" update. Inside your prepareRow() method, you can do something like the following:

class ExampleMigration extends Migration {
  public function prepareRow($row) {
      // If "updating" a product, protect these fields.
      // We know its updating if the product exists in the database with the sku.
      // Migrate updates by deleting an entire entity and replacing with
      // the new one. We circumvent the removal of the values of these
      // fields by pulling them and overriding the defaults provided
      // in the mapping.
      // You could do the same with a nid id found with a title, or something similar.
      // $row->migrate_map_sourceid1 is usually the entity id you're looking for,
      // our example here uses a commerce_product and loads it with the provided sku
      if ($product = commerce_product_load_by_sku($row->sku)) {
        // Use the metatdata wrapper to pull values
        $product_wrapper = entity_metadata_wrapper('commerce_product', $product);

        // field_stock
        // Some products have a NULL stock, lets keep the zero default if NULL
        if ($product_wrapper->field_stock->value() !== NULL) {
          $row->stock = $product_wrapper->field_stock->value();
        } else { $row->stock = 0; }

        // field_max
        $row->max = $product_wrapper->field_max->value();
      }
   }
}

WORD OF CAUTION: If you rollback records that have customized values, there is no protection from deleting these values. In other words, if you rollback an entity that has a protected field and then re-import it again, you will simply have the default value.

Comments

milos.kroulik’s picture

I assume, that $nid should be mapped in this scenario, otherwise old nodes won't be updated and new will be created, leading to duplicates.

fonant’s picture

No, I don't think you should map $nid, just let the migration mapping table handle that. Migrate will create new nodes and map their nids to the source IDs automatically.

What it does need is for the migrate_import to be called with the --update argument.

http://www.fonant.com - Fonant Ltd - Quality websites