7

As reported here I have big problems with huge vocabularies in Drupal 7. Now I want to empty the big vocabularies, but I can't do that via the admin interface, because its running out of memory, so it can't be loaded any more.

How can I delete all terms of a vocabulary form the command line using drush and MySQL?

I know, I could do something like that:

DELETE FROM `database`.`taxonomy_term_data` WHERE  `taxonomy_term_data`.`vid` = 17

But what else would I have to delete?

  • you want to remove a vocabulary alone? or a vocabulary and its items? – Aboodred1 Jun 12 '13 at 23:50
  • @Aboodred1 only its items, but together with everything that belongs to that items, as usage in fields etc. – user5950 Jun 12 '13 at 23:55
  • Don't run that query. Bad things will happen. – mpdonadio Jun 13 '13 at 1:40
  • @MPD Ok than, but how can I delete those terms? This must be possible some how. – user5950 Jun 15 '13 at 11:05
6

Untested; use for inspiration and test:

<?php

$vid = 17;

$tree = taxonomy_get_tree($vid);

if (count($tree) == 0) {
  print "Nothing to delete.\n";
}
else {
  $tree = array_slice($tree, 0, 1000);

  foreach ($tree as $term) {
    print 'Deleting tid ' . $term->tid . "\n";
    taxonomy_term_delete($term->tid);
  }
}

Put this in its own file, and execute as

drush -u 1 scr nuke_vid_18.php

Keep running it until it doesn't show anything as deleted. The array_slice is there to limit things so you don't run out of memory. You can potentially save some memory by querying directly, but taxonomy_get_tree() isn't terribly inefficient as long as you aren't doing full term loads.

Backup your database with drush sql-dump as a precaution before you do anything like this.

5

I've these modules: Drush and Devel For exclude all terms of taxonomy, use the generate-terms command:

drush generate-terms you_vocabulary_name 0 --kill

Change your_vocabulary_name to name of vocabulary you need delete terms

  • quite easy solution. thanks. why the --kill ? – xaa Apr 14 '16 at 8:59
2

You can use the following command:

drush -v eval 'foreach(taxonomy_get_tree(123) as $term) { taxonomy_term_delete($term->tid); }'

Where 123 is your vocabulary id which you should change.

If it doesn't work, make sure that you clear your cache (e.g. memcached).

You can get vid of your vocabulary name by the following command:

drush sqlq "SELECT name, vid FROM taxonomy_vocabulary WHERE name = 'vocabulary_name'"

See also:

2

You can also use https://www.drupal.org/project/taxonomy_multidelete_terms module to delete taxonomy terms.

This module makes it possible to delete multiple terms at one time. You need to select terms and click on delete button. All selected terms will be deleted. You can also delete all terms at one time.

  • Hi and welcome to Drupal Answers :) If you refer to a module, can you please include some summary or description from the module page? That gives the OP and other people a better indication of where you are linking to. Thanks! – Neograph734 Jan 5 '17 at 17:22
1

In addition to @mpdonadio code, I just added the snippet to load vid by the vocabulary's name. I hope it might help someone to save time.

$voca = "forums";
$vobj=taxonomy_vocabulary_machine_name_load("forums");
$vid = $vobj->vid;

$tree = taxonomy_get_tree($vid);

if (count($tree) == 0) {
    print "Nothing to delete.\n";
}
else {
   $tree = array_slice($tree, 0, 1000);

   foreach ($tree as $term) {
    print 'Deleting tid ' . $term->tid . "\n";
    taxonomy_term_delete($term->tid);
   }
}
0

You can create a drush command named vocabulary-clean. Create a module named drush_taxonomy, inside the drush_taxonomy.drush.inc file put this code:

<?php
/**
 * @file
 * Drush commands related to taxonomy.
 */

/**
* Implements hook_drush_command().
*/
function drush_taxonomy_drush_command() {
  $items['vocabulary-clean'] = array(
    'description' => dt("Delete all terms in a vocabulary."),
    'aliases' => array('vc'),
    'arguments' => array(
      'name' => dt('The vocabulary names to clean.'),
    ),
    'examples' => array(
      'drush vocabulary-clean tags' => dt('Delete all the terms in tags vocabulary'),
      'drush vocabulary-clean tags test' => dt('Delete all the terms in tags and test vocabularies'),

    ),
  );
  return $items;
}

/**
 * Callback for the vocabulary clean command.
 */
function drush_drush_taxonomy_vocabulary_clean() {
  $names = func_get_args();

  if (!empty($names)) {
    // Check for duplicate ids.
    $test_names = array_unique($names);
    if (count($test_names) != count($names)) {
      drush_set_error('DRUSH_VOCABULARY_CLEAN_ERROR', dt('You have duplicate vocabulary names.'));
      return;
    }
    //Searching the vocabularies in the site
    $vocabulary_in_db = array_column(taxonomy_get_vocabularies(), 'machine_name');
    $vocabulary_non_existent = array_diff($names, $vocabulary_in_db);
    $vocabulary_existent = array_diff($names, $vocabulary_non_existent);

    if(count($vocabulary_existent) == 0) {
      drush_set_error('DRUSH_VOCABULARY_CLEAN_ERROR', dt("The desired vocabularies to clean doesn't exists."));
      return;
    }

    if(count($vocabulary_non_existent)) {
      drush_print(dt("Non-existent vocabularies:"));
      drush_print(implode(' ', $vocabulary_non_existent));
    }

    foreach ($vocabulary_existent as $name) {
      $vid = taxonomy_vocabulary_machine_name_load($name)->vid;
      foreach(taxonomy_get_tree($vid) as $term) {
        taxonomy_term_delete($term->tid);
      }
    }

    drush_print(dt("Vocabularies cleaned:"));
    drush_print(implode(' ', $vocabulary_existent));
  }
  else {
    drush_set_error('DRUSH_VOCABULARY_CLEAN_ERROR', dt("You must enter at least one vocabulary name."));
  }
}

Install the module, run drush cc drush to clear the drush cache and use the command like this:

drush vc tags

or

drush vocabulary-clean tags

If you want add another alias to the command add elements to the aliases array like this:

'aliases' => array('vc', 'voc-clean', 'clean'),

And you can use this commands:

drush vc tags
drush voc-clean tags
drush clean tags

Always the output will be:

Vocabularies cleaned:
tags
0

Assuming Entity API is installed we can use entity_delete_multiple which should be faster than deleting one every time.

define("MY_VOCAB", "tags");

function _custom_zap_vocab() {
  $vocab = taxonomy_vocabulary_machine_name_load(MY_VOCAB);

  $tree = taxonomy_get_tree($vocab->vid);

  $tids = array_map(function($term){
    return $term->tid;
  }, $tree);

  entity_delete_multiple('taxonomy_term', $tids);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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