5

Now that content_alter_db() has been removed from D7, what is the recipe to update a field's schema?

My field needs to change from

function sheetnode_field_schema_7001($field) {
$columns = array(
  'value' => array(
    'description' => 'The worksheet content.',
    'type' => 'text',
    'size' => 'big',
    'not null' => TRUE,
  ),
);
$indexes = array();
return array(
  'columns' => $columns,
  'indexes' => $indexes,
);
}

to

function sheetnode_field_schema_7002($field) {
$columns = array(
  'value' => array(
    'description' => 'The worksheet content.',
    'type' => 'text',
    'size' => 'big',
    'not null' => TRUE,
  ),
  'name' => array(
    'description' => 'The worksheet title.',
    'type' => 'varchar',
    'length' => 255,
    'not null' => FALSE,
  ),
);
$indexes = array(
  'name' => array('name'),
);
return array(
  'columns' => $columns,
  'indexes' => $indexes,
);
}
  • Just to clarify: You are creating a module that defines a field type, right? So it is not about a specific field, but it has to be for all fields of this type. It seems clear after looking closely at your answer, but maybe not for other readers. – donquixote Apr 1 '18 at 1:49
10

Based on megadesk3000's answer, I ended up writing the following code:

function sheetnode_update_7002(&$sandbox) {
  $fields = field_info_fields();
  foreach ($fields as $field_name => $field) {
    if ($field['type'] == 'sheetfield' && $field['storage']['type'] == 'field_sql_storage') {
      $schema = sheetnode_field_schema_7002($field);
      foreach ($field['storage']['details']['sql'] as $type => $table_info) {
        foreach ($table_info as $table_name => $columns) {
          $column_name = _field_sql_storage_columnname($field_name, 'name');
          db_add_field($table_name, $column_name, $schema['columns']['name']);
          db_add_index($table_name, $column_name, array($column_name));
        }
      }
    }
  }
  field_cache_clear();
}

This seemed to work fine.

  • This worked for me, but to avoid the issue raised in drupal.org/node/150220 I included the current version of the schema in the update function. – marblegravy Oct 29 '12 at 5:28
3

This is modified version of @infojunkie code with support for multiple columns, so they should be re-created once missing.

/**
 * Re-create missing module field schema.
 */
function foo_field_update_7001(&$sandbox) {
  $field_type = 'foo_field'; // CHANGE THIS.
  $fields = field_info_fields();
  foreach ($fields as $field_name => $field) {
    if ($field['type'] == $field_type && $field['storage']['type'] == 'field_sql_storage') {
      $schema = foo_field_field_schema($field); // CHANGE THIS.
      foreach ($field['storage']['details']['sql'] as $type => $table_info) {
        foreach ($table_info as $table_name => $columns) {
          foreach ($schema['columns'] as $column => $data) {
            $column_name = _field_sql_storage_columnname($field_name, $column);
            db_add_field($table_name, $column_name, $schema['columns'][$column]);
            db_add_index($table_name, $column_name, array($column_name));
          }
        }
      }
    }
  } 
  field_cache_clear();
}
2

Have not done yet, but i would try something like this:

First you have to change the schema in hook_field_schema() to the new schema. Thats no problem, cause this hook is called, when you create an instance of that field. So all newly created fields will automatically use the new schema.

After that implement hook_update_n to update the tables of already created fields and do the following:

First get all the Instance names of fields that use the old schema:

SELECT field_name FROM field_config WHERE type='YOUR_FIELD_NAME';

With these instance names you can change the tables with the db api (db_add_field, db_change_field and db_drop_field for example) so they match your new field_schema. That would be 2 tables per result of the query above: field_data_INSTANCE_NAME and field_revision_INSTANCE_NAME

Run update.php after that.

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.