Comment changer le nom de machine d'un champ une fois qu'il a été créé

18

J'ai espacé tout en tapant le nom du champ et maintenant le nom de la machine n'est pas ce que je voulais qu'il soit. Je sais que c'est juste une gêne. mais je me demande s'il existe un moyen de modifier le nom de machine d'un champ une fois qu'il est créé.

Je suppose que cela m'amène à la deuxième partie de ma question. si j'ai créé un champ et qu'il n'est plus utilisé, comment puis-je le supprimer, faut-il le faire à partir de la base de données ou peut-il le faire quelque part dans l'interface utilisateur?

user379468
la source

Réponses:

15

En bref, vous ne pouvez pas changer le nom de la machine. En théorie, c'est évidemment possible, mais cela nécessitera pas mal de gâchis avec la base de données. Si vous venez de créer le champ, il est beaucoup plus facile de le supprimer et d'en créer un nouveau.

L'essentiel serait de renommer toutes les entrées field_configet field_config_instance, mais dès que vous commencez à utiliser le champ, les noms des machines sont stockés dans une centaine d'endroits différents. Vues de la configuration, de la configuration des panneaux , des fonctionnalités et plus encore, et d'ici là, la modifier n'est pas amusant.

La suppression des champs peut être effectuée sur admin/structure/types/manage/[machine_name_of_content_type]/fields:, accessible via l' onglet " Gérer les champs " sur n'importe quel type de contenu.

Létharion
la source
Mais les champs ne restent-ils pas encore dans la base de données, par exemple, j'ai créé un nouveau champ avec le nom du popper, cependant quand je vais ajouter un nouveau champ à un type de contenu, l'ancien nom de champ apparaît toujours en option. Peut-être que je ne comprends pas exactement comment les champs fonctionnent.
user379468
1
Il y a une fonctionnalité que je n'ai pas beaucoup étudiée, qui supprime les champs et leur contenu au fil du temps. La raison est d'empêcher un site de s'arrêter lors de la suppression d'un champ avec des milliers d'entrées. Si le champ n'est utilisé nulle part, je m'attendrais à ce qu'il disparaisse lors de la prochaine exécution cron.
Letharion
J'ai essayé de faire un sed -i -es / old_field / new_field / sur un code de site et un vidage de base de données. Malheureusement, quelque chose s'est mal passé et après le dysfonctionnement du site de restauration de la décharge. Des idées pour le faire correctement?
Dmitry Vyal
1
@Dmitry Vyal: Le nom du champ est stocké à quelques endroits dans un tableau sérialisé - le remplacement d'une chaîne par une autre chaîne d'une longueur différente romprait le unserialize () du tableau et probablement le prochain bootstrap ou Drupal.
Charlie Schliesser
@Charlie S: Merci, je m'en occuperai à l'avenir.
Dmitry Vyal
16

Ma procédure consiste à utiliser drush pour cloner le champ en premier, puis copier les données de champ avec des requêtes DB dans la nouvelle table de champ. Après avoir vérifié le contenu du champ cloné, je supprime le champ d'origine.

Je le fais de cette façon parce que je pense que la méthode drush de clonage des champs sera toujours au moins aussi fiable que n'importe quel code de clonage que je pourrais créer moi-même, la requête de copie de données est assez simple et je peux vérifier le nouveau champ avant de supprimer l'original .

  1. drush field-clone field_my_field field_my_field_clone
  2. Insérez des lignes dans field_my_field_clone, par exemple,INSERT field_my_field_clone SELECT * FROM field_my_field;
  3. Vérifiez le contenu de field_my_field_clone.
  4. Supprimez le champ à l'aide de l'interface utilisateur, par exemple, admin/structure/types/manage/my-content-type/fields
Keithm
la source
1
C'est bien! Pour D7: INSERT field_data_field_my_field_clone SELECT * FROM field_data_field_my_field; INSÉRER field_revision_field_my_field_clone SELECT * FROM field_revision_field_my_field;
joelpittet
Je ne savais pas qu'il y avait une commande "drush field-clone"! Awesome :)
Lovau
Qu'en est-il des vues, des panneaux, etc.? Corrections manuelles?
zkent
si vous utilisez drush, vous pouvez directement supprimer le champ avec drush field-delete xxxet vous pourriez aussi aimer drush sql-querycomme suggéré par neubreed. @zkent, vous devrez relier le nouveau champ dans les vues, panneaux, etc.
existants
6

J'ai écrit un script de mise à jour, qui crée en fait un nouveau champ et une nouvelle instance avec le nouveau nom de machine, copie toutes les anciennes données de champ dans la nouvelle et supprime enfin l'ancienne instance.

// Set variables
$old_name = 'field_old_name';
$new_name = 'field_new_name';
$entity_type = 'node';
$bundle = 'page';

// Get old field info
$old_field = field_info_field($old_name);

// Create new field
$new_field = $old_field;
$new_field['field_name'] = $new_name;

if (!field_info_field($new_name)) {
  field_create_field($new_field);
}
else {
  field_update_field($new_field);
}

// Get old field instance
$old_instance = field_info_instance($entity_type, $old_name, $bundle);
$new_instance = $old_instance;
$new_instance['field_name'] = $new_name;

if (!field_info_instance($entity_type, $new_name, $bundle)) {
  field_create_instance($new_instance);
}
else {
  field_update_instance($new_instance);
}

// Migrate old fields' data to the new ones
$field_data = db_select('field_data_' . $old_name, 'old')
  ->fields('old')
  ->condition('entity_type', $entity_type)
  ->condition('bundle', $bundle)
  ->execute();

while ($data = $field_data->fetchAssoc()) {
  $data_new = array();
  foreach ($data as $column => $value) {
    $column = str_replace($old_name, $new_name, $column);
    $data_new[$column] = $value;
  }
  db_insert('field_data_' . $new_name)
    ->fields($data_new)
    ->execute();
}

// Migrate old fields' revision data to the new ones
$field_revision = db_select('field_revision_' . $old_name, 'old')
  ->fields('old')
  ->condition('entity_type', $entity_type)
  ->condition('bundle', $bundle)
  ->execute();

while ($revision = $field_revision->fetchAssoc()) {
  $revision_new = array();
  foreach ($revision as $column => $value) {
    $column = str_replace($old_name, $new_name, $column);
    $revision_new[$column] = $value;
  }
  db_insert('field_revision_' . $new_name)
    ->fields($revision_new)
    ->execute();
}

// Delete old instance
field_delete_instance($old_instance);

// Purge fields
field_purge_batch(1000);
Елин Й.
la source
2

Je devais juste faire cela, et j'ai trouvé que ce n'était pas trop difficile, mais mon site est assez simple.

Essaye ça:

  1. Créez un nouveau champ avec le nom correct.
  2. Exécutez ces requêtes dans MySQL:
INSERT INTO field_data_[NEW MACHINE NAME] (entity_type, bundle, deleted, entity_id, revision_id, language, delta, field_fabric_color_pattern_tid) SELECT cf.* FROM  `field_data_[OLD MACHINE NAME]` cf
INSERT INTO field_revision_[NEW MACHINE NAME] (entity_type, bundle, deleted, entity_id, revision_id, language, delta, field_fabric_color_pattern_tid) SELECT cf.* FROM  `field_revision_[OLD MACHINE NAME]` cf

(remplacez [NOUVEAU NOM MACHNIE] et [ANCIEN NOM MACHINE] par field_your_field_names)

  1. Mettez à jour toutes les vues impliquées pour utiliser le nouveau champ et tous les autres modules qui pointent vers ce champ spécifique (c'est là que les choses peuvent devenir laides si votre site est compliqué). Vous pouvez voir toutes les vues qui utilisent votre ancien champ ici:/admin/reports/fields/views-fields
  2. Vider le cache du site
tmsimont
la source
2

// Modifiez les noms des tables de stockage des champs. Ici, nous modifions le nom de l'ancienne table avec un nouveau nom.

db_rename_table($data_table_name, 'field_data_' . $new_field_name);
db_rename_table($revision_table_name, 'field_revision_' . $new_field_name);

// Modifiez les noms de champ dans les tables field_config et field_instance_config.

db_update('field_config')
  ->fields(
    array(
      'field_name' => $new_field_name,
    )
  )
  ->condition('field_name', $field_name, '=')
  ->execute();

db_update('field_config_instance')
  ->fields(
    array(
      'field_name' => $new_field_name,
    )
  )
  ->condition('field_name', $field_name, '=')
  ->execute();
Sneha Surve
la source
1

Avec la réponse drush field-clone ci-dessus, vous pouvez également effectuer la dernière étape MySQL avec Drush (exemple D7):

drush sql-query "INSERT field_data_field_my_field_clone SELECT * FROM field_data_field_my_field"

drush sql-query "INSERT field_revision_field_my_field_clone SELECT * FROM field_revision_field_my_field"
neubreed
la source
0

Si vous ne voulez pas jouer avec mysql, vous pouvez essayer un script drush que j'ai écrit, appelé copie de la valeur du champ.

Vous devrez d'abord configurer votre nouveau champ, puis appeler

drush fieldcopy OLDFIELDNAME NEWFIELDNAME

Cela déplacera les données existantes vers le nouveau champ une fois terminé, supprimez l'ancien champ.

Pontus Nilsson
la source
-3

Exportez le fichier SQL de votre base de données, utilisez la ligne de commande sedpour remplacer toutes les occurrences du terme à modifier et réimportez votre base de données.

gvi
la source
1
A rejeté votre commentaire car cette approche va faire des ravages sur votre installation Drupal car il y a quelques endroits dans la base de données où les noms de champs sont sérialisés en PHP. Pour plus d'informations à ce sujet, consultez les commentaires de @CharlieS (et d'autres) sous la réponse acceptée ci-dessus.
hargobind