I'm trying to create a hierarchical taxonomy from a perpared migration database table which looks like that:

 0 | FOO  |       
 1 | BAR  |       
 2 | LORE | FOO
 3 | IPSE | FOO
 4 | DOLO | BAR

It's a pretty messy data structure, but fact is there are parent and child terms in one table.

What I did so far is migrating the parent terms first. Now my custom taxonomy looks like this:

|_ FOO
|_ BAR

The migration code snipped I used to achieve this works like that:

$this->addFieldMapping('name', 'PARENT');

Until now everything works as expected!

Now, in a second migration step I want to add the child terms like that to my taxonomy:

|_ FOO
  |_ LORE
  |_ IPSE
|_ BAR
  |_ DOLO

What I tried is to add a hierarchical mapping to my migration:

$this->addFieldMapping('name', 'NAME');
$this->addFieldMapping('parent_name', 'PARENT')
    ->arguments(array('source_type' => 'name'));

But this does not work, the result is an unhierarchical list like that:

|_ FOO
|_ BAR

Did anyone try to do something like this before? Any ideas? Thanks!


1 Answer 1


I had to migrate a nested Vocabulary from Drupal 6 to Drupal 7. My Strategy was:

  1. Migrate the plain terms
  2. Use the postImport() of Migrate-API to map the Parent-Relationship

    public function postImport() {
    // Get alle Terms from features_dd_private_contact_form_subjects
    // Query zum Laden der Daten aus Drupal6
    $source_query = Database::getConnection('legacy', 'legacy')
      ->select('term_data', 't');
    // Join Terms with voab
    $source_query->join('vocabulary', 'v', 'v.vid = t.vid');
    // Join Hierarchy
    $source_query->join('term_hierarchy', 'th', 'th.tid = t.tid');
    $source_query->condition('th.parent', '0', '<>');
    $source_query->fields('th', array());
    $source_records = $source_query->execute();
    foreach ($source_records as $source_record) {
      // Term-ID in destination db.
      $dest_tid = $this->get_destination_tid_by_old_tid($source_record->tid);
      // Parent-Tid in the destination.
      $dest_parent_tid = $this->get_destination_tid_by_old_tid($source_record->parent);
      $child_term = taxonomy_term_load($dest_tid);
      $child_term->parent = $dest_parent_tid;


  • This is fine for small migrations. I'd rather stick with prepareRow public function, where you can change the the data before saving for each record. This way you interact with each record separetly rather then updating (taxonomy_term_save) all at once.
    – David
    Aug 3, 2018 at 8:42

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.