Kalin Chernev

Convert a text to textarea type of field in Drupal 7 (Elegant way)

Converting a text field in Drupal 7 from one type to another is a frequently encounter task, especially in times when the field text length haven’t been planned well.

Most of the times, site builders add another field with the corresponding type, delete the old one. However, in larger projects, where the “machine” name (the system name) is used throughout modules and themes, we need to keep this name intact, keep all the data entered in the database so far, and still change the type. From site building point of view, this operation is impossible on first place if users have entered data in old-type-field on first place – Drupal won’t let you delete the field before deleting all the content.

Our approach

  1. We need to query the database in a way to only change the type of the field in a scalable way, no data should be lost!
  2. Also, we have to make sure changes do not require users and developers to edit the database tables in anyway! The solution have to be as safe as possible!
  3. Changes have to be managed throught code (again best practices and scalability)
  4. Use Drupal API functions as much as possible.

Simple example would be when we have the following form – the fields in read are those text fields we are going to convert to text area such.

Drupal form initially

In a Drupal module file, we place the following code (quick link to the developers documentation if you need help for writing the module)

 * Change field_inq_description field from textfield to textarea
function pip_inquiry_update_7001() {
  // Manual database changes.
  db_query("UPDATE {field_config} SET type = 'text_long' WHERE field_name = 'field_inq_description'");
  db_change_field('field_data_field_inq_description', 'field_inq_description_value', 'field_inq_description_value', array(
    'type' => 'varchar',
    'length' => '20000',
  db_change_field('field_revision_field_inq_description', 'field_inq_description_value', 'field_inq_description_value', array(
    'type' => 'varchar',
    'length' => '20000',
  // Clear caches.
  // Apply the new field instance configuration.
    'pip_inquiry_show' => array('field'),

 * Change field_inq_camp_description field from textfield to textarea
function pip_inquiry_update_7002() {
  // Manual database changes.
  db_query("UPDATE {field_config} SET type = 'text_long' WHERE field_name = 'field_inq_camp_description'");
  db_change_field('field_data_field_inq_camp_description', 'field_inq_camp_description_value', 'field_inq_camp_description_value', array(
    'type' => 'varchar',
    'length' => '20000',
  db_change_field('field_revision_field_inq_camp_description', 'field_inq_camp_description_value', 'field_inq_camp_description_value', array(
    'type' => 'varchar',
    'length' => '20000',
  // Clear caches.
  // Apply the new field instance configuration.
    'pip_inquiry_show' => array('field'),

The hook we implement is the hook_update_N, it lets us communicate to site users and developers that there are updates in the system (via the update.php script)

Updates in Drupal

The following functions are used to apply changes in the database:

  • db_query for changing the type of the field to “text_long” which is the type we need to have in the end of the update script
  • db_change_field for changing field definition
  • field_cache_clear to clear the cache about fields information
  • features_revert to revert all features related to the changes applied

It won’t hurt if you clear the overall cache :)

After the updates, configurations and edit form for the entity are correctly taking long text values:

updated form


It’s always good to think scalability when you modify database schema, and even more when existing information has to be contained intact. Best approach for Drupal would include the implementation of it’s API as much as possible. Our example is for changing the type of a text field to long text area one, still you can convert between other types of fields as well in a similar manner.


  1. dennis

    good article thank you for sharing…

  2. Adrien L

    Thanks a lot for this example, I had to change few fields for a project I’m working on right now and was not very pleased to delete / recreate all these fields by hand !


  3. Etienne

    Very clear and useful, thanks a lot !

    • Tadayasu

      Hi All, What a fantastic idea. I am looknig forward to participating. At the moment, however, on the rally page I am seeing a lot of red x’s. I have tried refreshing the page with no luck. Coconut Bliss is x’d, everything after Kitchen Werks is also x’d.At the top of the Contact Us page I can see the coding for the page Wishing you loads of luck with your endeavor!

    • Roman

      This is just a guess, but as somebody who is a neibwe to using CMS, I was asking myself a similar question: I want to use Drupal (or some other CMS) to maintain a site that until now has consisted mainly of static web pages. Visitors of the site do not and should not be able to log in nor should they see any log-in form. So the first thing I asked myself after I installed Drupal and browsed to the default generated site is: how to remove the login form so that site visitors do not see that one can log in to this site at all.What I really would like though is a way that totally disallows any log in for visitors from the WAN and only allows admin logins from our company-internal LAN.

  4. Oneng

    Thanks man!
    very useful article -))

  5. Sebastian

    Im trying to do it fow convert integer field to decimal field and I see these notices

    Notice: Undefined index: precision in number_field_schema() (line 35 of /home/servilla/public_html/servillantasgiraldo.com.co/modules/field/modules/number/number.install).
    Notice: Undefined index: scale in number_field_schema() (line 36 of /home/servilla/public_html/servillantasgiraldo.com.co/modules/field/modules/number/number.install).

  6. Kalin

    @Sebastian, looks like the hook hasn’t covered all cases of conversion.
    There is a similar unclosed issue at https://drupal.org/node/1815536 and I also found another hint at http://drupal.stackexchange.com/questions/32986/change-database-column-type-in-hook-update-n

    Try to add more these additional attributes to the array: ‘precision’, ‘scale’ and ‘not null’, most probably if you debug the update hook, you’ll find that the decial conversion needs those to work correctly as the database schema needs to know the precision of your decialms.

  7. ajay gadhavana

    hi i have created module same as you told its work perfectly and change value in database but still its give Error message
    “name: the text may not be longer than 255 characters.”

    due to error i have not added “features_revert “statements

  8. Milos

    I tried your approach and it works very well, thanks.

    My 2 cents:
    - documentation for db_change_field() mentions, that we should always use db_drop_() function before it
    - I had a problem, when I tried to use this snippet on PostgreSQL. There is a bug in Drupal core, which causes generating wrong SQL. Patch (working in my case) can be found at https://www.drupal.org/node/1668644#comment-6826762

  9. romain

    Thanks for your article.
    Maybe in futur the hook_field_schema_alter will be in core …

    • Suyapa

      Woah this weblog is werodnful i really like studying your posts. Stay up the great work! You recognize, many persons are looking round for this information, you can aid them greatly.

  10. Brian Dombrowski

    Thanks for posting! I found that some remnants of the text field type in the database using your method, so I took a different approach. But super thanks for bootstrapping my approach! You can check it out if you want on my blog.


  11. MrSky

    Thank u so much, this provided me a complete solution for my current issue. Great sharing!!!

Leave a comment


Please enter the CAPTCHA text