¿Cómo cambio el nombre de la máquina de un campo una vez que se ha creado?

18

Me separé mientras escribía el nombre del campo y ahora el nombre de la máquina no es lo que quería que fuera. Sé que es solo una molestia. pero me pregunto si hay alguna forma de alterar el nombre de la máquina de un campo una vez que se crea.

Supongo que esto me lleva a la segunda parte de mi pregunta. si creé un campo y ya no se usa, ¿cómo hago para eliminarlo? ¿Esto tiene que hacerse desde la base de datos o puede hacerse en algún lugar de la interfaz de usuario?

usuario379468
fuente

Respuestas:

15

En resumen, no puede cambiar el nombre de la máquina. En teoría, es obviamente posible, pero requerirá bastante desorden con la base de datos. Si acaba de crear el campo, es mucho más fácil eliminarlo y crear uno nuevo.

Lo básico sería cambiar el nombre de todas las entradas field_configy field_config_instance, pero tan pronto como comience a usar el campo, los nombres de las máquinas se almacenan en cientos de lugares diferentes. Vistas de configuración, los paneles de configuración, características y más, y para entonces, el cambio es no divertido.

La eliminación de campos se puede realizar en:, al admin/structure/types/manage/[machine_name_of_content_type]/fieldsque puede acceder a través de la pestaña " Administrar campos " en cualquier tipo de contenido.

Letharion
fuente
Pero los campos aún no permanecen en la base de datos, por ejemplo, creé un nuevo campo con el nombre emergente, sin embargo, cuando voy a agregar un nuevo campo a un tipo de contenido, el nombre del campo anterior todavía aparece como una opción. Quizás no entiendo exactamente cómo funcionan los campos.
user379468
1
Hay una funcionalidad que no he investigado mucho, que elimina campos y su contenido con el tiempo. El motivo es evitar que un sitio se detenga al eliminar campos con miles de entradas. Si el campo no se usa en ninguna parte, esperaría que desapareciera en la próxima ejecución cron.
Letharion
Traté de hacer un sed -i -es / old_field / new_field / en un volcado de código de sitio y base de datos. Desafortunadamente, algo salió mal y después de que el sitio de restauración del vertedero no funcionaba correctamente. ¿Alguna idea de cómo hacerlo correctamente?
Dmitry Vyal
1
@Dmitry Vyal: el nombre del campo se almacena en algunos lugares en una matriz serializada: reemplazar una cadena con otra cadena de una longitud diferente rompería la deserialización () de la matriz y probablemente rompería el siguiente arranque o Drupal.
Charlie Schliesser
@ Charlie S: Gracias, nos ocuparemos de eso en el futuro.
Dmitry Vyal
16

Mi procedimiento es usar drush para clonar el campo primero, luego copiar los datos del campo con consultas DB en la nueva tabla de campos. Después de verificar el contenido del campo clonado, elimino el campo original.

Lo hago de esta manera porque creo que el método drush de clonar campos siempre será al menos tan confiable como cualquier código de clonación que pueda crear, la consulta de copia de datos es bastante simple y puedo verificar el nuevo campo antes de eliminar el original .

  1. drush field-clone field_my_field field_my_field_clone
  2. Insertar filas en field_my_field_clone, por ejemplo,INSERT field_my_field_clone SELECT * FROM field_my_field;
  3. Verificar el contenido de field_my_field_clone.
  4. Eliminar el campo usando la interfaz de usuario, por ejemplo, admin/structure/types/manage/my-content-type/fields
keithm
fuente
1
¡Esto es genial! Para D7: INSERTAR field_data_field_my_field_clone SELECT * FROM field_data_field_my_field; INSERTAR field_revision_field_my_field_clone SELECT * FROM field_revision_field_my_field;
joelpittet
¡No sabía que había un comando "drush field-clone"! Impresionante :)
Lovau
¿Qué pasa con las vistas, paneles, etc.? Arreglos manuales?
zkent
si está utilizando drush, puede eliminar directamente el campo drush field-delete xxxy también puede hacer lo drush sql-queryque sugiere neubreed. @zkent, deberá volver a vincular el nuevo campo en las vistas, paneles, etc. existentes
xaa
6

He escrito un script de actualización, que en realidad crea un nuevo campo e instancia con el nuevo nombre de la máquina, copia todos los datos del campo antiguo al nuevo y finalmente elimina la instancia anterior.

// 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);
Елин Й.
fuente
2

Simplemente tenía que hacer esto, y descubrí que no era demasiado difícil, pero mi sitio es bastante simple.

Prueba esto:

  1. Cree un nuevo campo con el nombre propio.
  2. Ejecute estas consultas en 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

(cambie [NUEVO NOMBRE DE MÁQUINA] y [NOMBRE DE MÁQUINA ANTERIOR] con field_your_field_names)

  1. Actualice las vistas involucradas para usar el nuevo campo y cualquier otro módulo que apunte a ese campo específico (aquí es donde las cosas pueden ponerse feas si su sitio es complicado). Puede ver las vistas que usan su campo anterior aquí:/admin/reports/fields/views-fields
  2. Borrar caché del sitio
tmsimont
fuente
2

// Cambiar los nombres de la tabla de almacenamiento de campo. Aquí estamos alterando el nombre de la tabla anterior con un nombre nuevo.

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

// Cambia los nombres de campo en las tablas field_config y 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 Survey
fuente
1

Con la respuesta drush field-clone anterior, puede hacer el último paso de MySQL con Drush también (ejemplo 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
fuente
0

Si no quieres jugar en mysql, puedes probar un script drush que escribí llamado Copia de valor de campo.

Primero deberá configurar su nuevo campo y luego llamar

drush fieldcopy OLDFIELDNAME NEWFIELDNAME

Esto moverá los datos existentes al nuevo campo una vez que haya terminado, elimine el campo anterior.

Pontus Nilsson
fuente
-3

Exporte el archivo SQL de su base de datos, use la línea de comando sedpara reemplazar todas las apariciones del término a cambiar y vuelva a importar su base de datos.

gvi
fuente
1
Desestimó su comentario porque este enfoque causará estragos en su instalación de Drupal ya que hay algunos lugares en la base de datos donde los nombres de campo son serializados en PHP. Para obtener más información sobre esto, consulte los comentarios de @CharlieS (y otros) en la respuesta aceptada arriba.
hargobind