18

I spaced out while typing the field name an now the machine name is not what I wanted it to be. I know it's just an annoyance. but I'm wondering if there is some way to alter the machine name of a field once it is created.

I suppose this leads me into the second part of my question. if I created a field, and it is no longer being used, how do I go about deleting it, does this have to be done from the database, or can it be done somewhere in the UI.

10 Answers 10

16

In short, you can't change the machine name. In theory, it's obviously possible, but it will require quite a bit of messing with the database. If you've only just created the field, it's far easier to remove it and create a new one.

The basics would be to rename all entries on field_config and field_config_instance, but as soon as you start using the field, the machine names get's stored in a hundred different places. Views config, Panels config, Features and more, and by then, changing it is not fun.

Deleting fields can be done on: admin/structure/types/manage/[machine_name_of_content_type]/fields, which you can reach through the "Manage fields" tab on any content type.

  • But don't the fields still remain in the database, for instance, I created a new field with the popper name, however when I go to add a new field to a content type, the old field name still appears as an option ... perhaps I'm not understanding exactly how fields work. – user379468 Jan 12 '12 at 21:39
  • 1
    There is a functionality that I haven't investigated a lot, that deletes fields and their content over time. The reason is to prevent that a site grinds to a halt when deleting a fields with thousands of entries. If the field is not used anywhere, I would expect it to go away on the next cron run. – Letharion Jan 12 '12 at 21:46
  • I tried to do a sed -i -e s/old_field/new_field/ on a site code and database dump. Unfortunately, something went wrong and after the dump restoration site was malfunctioning. Any ideas how to do it right way? – Dmitry Vyal Aug 27 '12 at 7:25
  • 1
    @Dmitry Vyal: The field name is stored in a few places in a serialized array – replacing one string with another string of a different length would break the unserialize() of the array and probably break the next bootstrap or Drupal. – Charlie Schliesser Dec 31 '12 at 16:49
  • @Charlie S: Thanks, will take care of it in the future. – Dmitry Vyal Jan 2 '13 at 10:28
15

My procedure is to use drush to clone the field first, then copy the field data with DB queries into the new field table. After I verify the contents of the cloned field, I delete the original field.

I do it this ways because I think the drush method of cloning fields will always be at least as reliable as any cloning code I might craft myself, the data copy query is pretty simple, and I get to check the new field before deleting the original.

  1. drush field-clone field_my_field field_my_field_clone
  2. Insert rows into field_my_field_clone, e.g., INSERT field_my_field_clone SELECT * FROM field_my_field;
  3. Verify the contents of field_my_field_clone.
  4. Delete the field using the UI, e.g., admin/structure/types/manage/my-content-type/fields
  • This is great! For D7: INSERT field_data_field_my_field_clone SELECT * FROM field_data_field_my_field; INSERT field_revision_field_my_field_clone SELECT * FROM field_revision_field_my_field; – joelpittet Jun 17 '14 at 20:55
  • I didn't know there was a "drush field-clone" command ! Awesome :) – Lovau Mar 2 '15 at 14:54
  • What about views, panels, etc? Manual fixes? – zkent Aug 5 '15 at 3:37
  • if you are using drush you can direclty delete the field with drush field-delete xxx and you could also like drush sql-query as suggested by neubreed. @zkent, you will have te relink the new field in the existing views, panels, etc. – xaa Dec 9 '15 at 1:38
10

In Drupal 7, you can use the Field Rename module. In Drupal 6, you can use CCK field rename module.

5

I have written an update script, which actually creates a new field and instance with the new machine name, copies all the old field data to the new one and lastly deletes the old 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);
2

I just had to do this, and found it to not be too difficult, but my site is fairly simple.

Try this:

  1. Create a new field with the proper name.
  2. Run these queries in 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

(swap out [NEW MACHNIE NAME] and [OLD MACHINE NAME] with field_your_field_names)

  1. Update any views involved to use the new field, and any other modules that point to that specific field (this is where things might get ugly if your site is complicated). You can see any views that use your old field here: /admin/reports/fields/views-fields
  2. Clear site cache
2

// Change the field storage table names. Here we are altering the name of the old table with new name.

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

// Change the field names in the field_config and field_instance_config tables.

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();
1

With the drush field-clone answer above you can do the last MySQL step with Drush also (D7 example):

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"
0

The db_change_field() function may help you.

0

If you don't want to fiddle around in mysql you could try a drush script I wrote called Field value copy.

You will need to setup your new field first and then call

drush fieldcopy OLDFIELDNAME NEWFIELDNAME

This will move existing data to the new field once done delete the old field.

-3

Export the SQL file of your database, use the command line sed to replace all occurrences of the term to change, and re-import your database.

  • 1
    Downvoted your comment because this approach will wreak havoc on your Drupal installation since there are a few places in the database where the field names are PHP serialized. For more information about this, see the comments from @CharlieS (and others) under the accepted answer above. – hargobind Feb 19 '14 at 4:26

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.