Comme indiqué ici J'ai de gros problèmes avec d'énormes vocabulaires dans Drupal 7. Maintenant, je veux vider les gros vocabulaires, mais je ne peux pas le faire via l'interface d'administration , car il manque de mémoire, il ne peut donc plus être chargé.
Comment puis-je supprimer tous les termes d'un vocabulaire de la ligne de commande en utilisant drush
et MySQL?
Je sais, je pourrais faire quelque chose comme ça:
DELETE FROM `database`.`taxonomy_term_data` WHERE `taxonomy_term_data`.`vid` = 17
Mais que devrais-je supprimer d'autre?
Non testé; utiliser pour l'inspiration et le 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);
}
}
Mettez-le dans son propre fichier et exécutez-le
drush -u 1 scr nuke_vid_18.php
Continuez à l'exécuter jusqu'à ce qu'il ne montre rien comme supprimé. Le array_slice
Est là pour limiter les choses afin que vous ne manquiez pas de mémoire. Vous pouvez potentiellement économiser de la mémoire en interrogeant directement, mais taxonomy_get_tree()
n'est pas terriblement inefficace tant que vous ne faites pas de charges complètes.
Sauvegardez votre base de données avec drush sql-dump
Par mesure de précaution avant de faire quelque chose comme ça.
J'ai ces modules: Drush et Devel Pour exclure tous les termes de taxonomie, utilisez la commande generate-terms:
drush generate-terms you_vocabulary_name 0 --kill
Remplacez votre_vocabulaire_nom par le nom du vocabulaire dont vous avez besoin de supprimer les termes
Vous pouvez utiliser la commande suivante:
drush -v eval 'foreach(taxonomy_get_tree(123) as $term) { taxonomy_term_delete($term->tid); }'
Où 123 est votre identifiant de vocabulaire que vous devez modifier.
Si cela ne fonctionne pas, assurez-vous de vider votre cache (par exemple memcached).
Vous pouvez obtenir vid
de votre nom de vocabulaire par la commande suivante:
drush sqlq "SELECT name, vid FROM taxonomy_vocabulary WHERE name = 'vocabulary_name'"
Voir également:
Vous pouvez également utiliser le module https://www.drupal.org/project/taxonomy_multidelete_terms pour supprimer les termes de taxonomie.
Ce module permet de supprimer plusieurs termes à la fois. Vous devez sélectionner les termes et cliquer sur le bouton Supprimer. Tous les termes sélectionnés seront supprimés. Vous pouvez également supprimer tous les termes en même temps.
En plus du code @mpdonadio, je viens d'ajouter l'extrait pour charger vid par le nom du vocabulaire. J'espère que cela pourrait aider quelqu'un à gagner du temps.
$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);
}
}
Aujourd'hui, il est également facile de le faire avec la console Drupal. Exemple: supprimer tous les termes du vocabulaire "tags"
taxonomie drupal: terme: suppression de balises
Vous pouvez créer une commande drush nommée vocabulary-clean
. Créez un module nommé drush_taxonomy
, à l'intérieur de drush_taxonomy.drush.inc
fichier mettre ce 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."));
}
}
Installez le module, exécutez drush cc drush
pour vider le cache drush et utiliser la commande comme ceci:
drush vc tags
ou
drush vocabulary-clean tags
Si vous souhaitez ajouter un autre alias à la commande, ajoutez des éléments au tableau d'alias comme ceci:
'aliases' => array('vc', 'voc-clean', 'clean'),
Et vous pouvez utiliser ces commandes:
drush vc tags
drush voc-clean tags
drush clean tags
La sortie sera toujours:
Vocabularies cleaned:
tags
En supposant que l'API d'entité est installée, nous pouvons utiliser entity_delete_multiple qui devrait être plus rapide que d'en supprimer une à chaque fois.
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);
}