Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove traces of Fields that belonged to a module content type?

I am trying to learn how to create a custom content type programmatically from within my module.

However, after uninstalling and reinstalling my module I was getting an error stating that one or more of the fields I was trying to create could not be created because they already exist.

So I went hacking through my databse, removing the content type and all tables that belonged to it.

Same result -- field already exists.

Next I went to the Drupal API website looking for ways to delete fields and field instances, and came across

field_delete_field()

and

field_delete_instance()

I made a php page to try to delete the fields that I had created, only to get an error stating that the table I was trying to delete does not exist.

So I'm kinda stuck -- I can't create the fields because they already exist, and I can't delete them because they don't exist!

BTW the code I was modeling my module after is the code found in the "node_example" section of the Drupal examples module.

like image 809
Tyler Avatar asked Nov 28 '12 15:11

Tyler


1 Answers

Ouch, deleting the database tables manually is never a good idea - Drupal's not that forgiving :)

Just to address the code in your install/enable hook, wrap the field creation in:

if (!field_info_field('field_name')) {
  field_create_field(...
}

That will stop the problem happening again. Or if you don't want to do that, make sure the field is deleted in the uninstall/disable hook. Obviously that method would potentially result in data loss.

To address the current problem, follow this process:

  • Completely uninstall (not just disable) your custom module. If it's in an inconsistent state, just delete its row in the system table.
  • Delete all traces of the field from the field_config and field_config_instance tables.
  • Truncate all the cache tables manually (any table beginning with cache_).
  • Not strictly necessary but clear up any lingering content:

    $nids = db_query('SELECT nid FROM {node} WHERE type = :type', array(':type' => 'type'))->fetchCol();
    node_delete_multiple($nids);
    

That ought to do it.

Any time you delete a field, through the UI or programatically you'll need to either run cron or call field_purge_batch() to 'hard' delete the fields as they're only marked for deletion in the first instance.

like image 90
Clive Avatar answered Oct 11 '22 14:10

Clive