2

Hello I need to update the field type of one of my content types. The content type is of a module so I need to do this with the Drupal API for let users update the module for their 7.x-1.0 branch.

This is the hook for update the field, I need to change it from Integer to Decimal like this:

 /**
 * Change field_inq_description field from Integer to Decimal
 */
function field_updates_update_7100() {
  // Manual database changes.
  db_query("UPDATE {field_config} SET type = 'number_decimal' WHERE field_name = 'field_rin'");
  db_change_field('field_data_field_rin', 'field_rin_value', 'field_rin_value', array(
    'type' => 'numeric',
    'precision' => '10',
    'scale' => '2',
  ));
  db_change_field('field_revision_field_rin', 'field_rin_value', 'field_rin_value', array(
    'type' => 'numeric',
    'precision' => '10',
    'scale' => '2',
  ));
  // Clear caches.
  field_cache_clear(TRUE);
  // Apply the new field instance configuration.
}

After I apply the update with update.php script I get these notices everywhere in the test website.

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).

What Im I doing wrong?

0

2 Answers 2

3

You just need to add precision and scale to the field config settings:

// API way.
$field = field_info_field('field_rin');
$field['settings']['precision'] = 10;
$field['settings']['scale'] = 2;
field_update_field($field);

// Raw way (shorthand, you'll want to add error checking).
$data = unserialize(db_query("SELECT data FROM {field_config} WHERE field_name = 'field_rin'")->fetchField());
$data['settings']['precision'] = 10;
$data['settings']['scale'] = 2;

db_update('field_config')
  ->fields(array('data' => serialize($data)))
  ->condition('field_name', 'field_rin')
  ->execute();
3
  • Hello thanks for your help, I have added the //API way you suggested, but the update breaks if the user has content created of that content type. It shows me this error in the update.php page Failed: FieldUpdateForbiddenException: field_sql_storage cannot change the schema for an existing field with data
    – svelandiag
    Apr 30, 2014 at 19:02
  • I used another function like instead of field_update_field($field); I used drupal_write_record('field_config', $field, array('id')); The update did not showed errors but Im still having these notices... =(
    – svelandiag
    Apr 30, 2014 at 19:04
  • Yeah that exception makes sense - you'll probably have to go down the manual route (you won't raise any exceptions that way)
    – Clive
    Apr 30, 2014 at 20:30
0

I found the answer, the help of Clive was great. Look this is the final code:

/**
 * Change field_inq_description field from Integer to Decimal
 */
function field_updates_update_7104() {
  // Manual database changes.
  db_query("UPDATE {field_config} SET type = 'number_decimal' WHERE field_name = 'field_rin'");
  db_change_field('field_data_field_rin', 'field_rin_value', 'field_rin_value', array(
    'type' => 'numeric',
    'precision' => '10',
    'scale' => '2',
  ));
  db_change_field('field_revision_field_rin', 'field_rin_value', 'field_rin_value', array(
    'type' => 'numeric',
    'precision' => '10',
    'scale' => '2',
  ));

    // Doing it with the raw way is the best choice.
    $data = unserialize(db_query("SELECT data FROM {field_config} WHERE field_name = 'field_rin'")->fetchField());
    $data['settings']['precision'] = 10;
    $data['settings']['scale'] = 2;

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

  // Clear caches.
  field_cache_clear(TRUE);

If you do it with the API way clive suggested and if you already have nodes of that content type the update.php script will show you an sql error telling you that you cannot update field properties with existing data, So the raw way clive suggested is the best way for do it. Thanks to Clive

Not the answer you're looking for? Browse other questions tagged or ask your own question.