This feature may be a bit way out there, but I think it is worth proposing for 2.6.

I have been migrating users into a site with some existing content. Some of these users may exist in the data already. Migrate currently doesn't handle this very well (or at least as far as I have been able to get it to work).

What I am proposing is something like this. When setting a field mapping to be able to mark it as a global uid. In these cases migrate will check the existing destination table and see if there is something that matches. It will then map against the existing content, and other mappings may have properties that say to leave, overwrite, or have a custom callback to merge in the case that there is pre existing content.

In my case I would mark email address as a global uid, as whatever the username on different systems the same email address will belong to the same person. I can see it also applying to things like RDF URIs and UUIDs?

$this->addFieldMapping('mail', 'user_email')->setGlobalUnique();
$this->addFieldMapping('picture', 'user_avatar')->mergeBehaviour(MIGRATE_MERGE_LEAVE);

Is this something that fits with the vision of migrate moving forward? I am happy to have a stab at coding it if it is.

Comments

mikeryan’s picture

This concept would be useful, although the "globally unique" phrase I find very confusing. What you want is to map an incoming source object to a pre-existing destination object (instead of creating a new one) when a given field matches on the existing object. I've done this with role migrations in migrate_d2d, and it would be good (if difficult) to generalize the concept. Note that you need to be sure when doing this to set rollbackAction to MigrateMap::ROLLBACK_PRESERVE (when rolling back, you don't want to delete objects that existed before you imported).

Knowing how applyMappings() works, the API as suggested here would be problematic - you'd have to be careful that your merge field was mapped first, for the merge action on other mappings to be applied. Better would be to have 'merge_field' as an option on the destination. And each destination would have to specifically support it - there's no general way to know where to look for the matching field (users table, node table, etc.). And I'm not where exactly in the workflow the check would be done, such that you could have differing merge actions on different fields...

I'm certainly open to a patch - this is going to take quite a bit of thought, though, particularly if you want the merge action concept (simply mapping to an existing object without overwriting it at all would be a simpler first step).

pifagor’s picture

Issue summary: View changes
Status: Active » Closed (outdated)