8.2.x database.inc db_add_field($table, $field, $spec, $keys_new = array())
8.0.x database.inc db_add_field($table, $field, $spec, $keys_new = array())
8.1.x database.inc db_add_field($table, $field, $spec, $keys_new = array())
8.3.x database.inc db_add_field($table, $field, $spec, $keys_new = [])
6.x database.pgsql.inc db_add_field(&$ret, $table, $field, $spec, $new_keys = array())
6.x database.mysql-common.inc db_add_field(&$ret, $table, $field, $spec, $keys_new = array())
7.x database.inc db_add_field($table, $field, $spec, $keys_new = array())

Adds a new field to a table.

Parameters

$table: Name of the table to be altered.

$field: Name of the field to be added.

$spec: The field specification array, as taken from a schema definition. The specification may also contain the key 'initial'; the newly-created field will be set to the value of the key in all rows. This is most useful for creating NOT NULL columns with no default value in existing tables.

$keys_new: (optional) Keys and indexes specification to be created on the table along with adding the field. The format is the same as a table specification, but without the 'fields' element. If you are adding a type 'serial' field, you MUST specify at least one key or index including it in this array. See db_change_field() for more explanation why.

See also

db_change_field()

Related topics

25 calls to db_add_field()
aggregator_update_7000 in modules/aggregator/aggregator.install
Add hash column to aggregator_feed table.
aggregator_update_7002 in modules/aggregator/aggregator.install
Add queued timestamp.
comment_update_7002 in modules/comment/comment.install
Rename {comments} table to {comment} and upgrade it.
comment_update_7003 in modules/comment/comment.install
Split {comment}.timestamp into 'created' and 'changed', improve indexing on {comment}.
comment_update_7004 in modules/comment/comment.install
Upgrade the {node_comment_statistics} table.

... See full list

File

includes/database/database.inc, line 2899
Core systems for the database layer.

Code

function db_add_field($table, $field, $spec, $keys_new = array()) {
  return Database::getConnection()->schema()->addField($table, $field, $spec, $keys_new);
}

Comments

Bagz’s picture

Refer to the Schema API (http://drupal.org/developing/api/schema) for more specific information about the parameters, in particular http://drupal.org/node/146939 for more information about what goes into the specification array, and http://drupal.org/node/159605 for more information about the various data types.

Rob230’s picture

I couldn't find any examples of using this to modify a table of another module in Drupal 7. Eventually I managed to get it to work like this:

function my_module_schema_alter() {
  $schema['existing_table']['fields']['new_field'] = array(
    'type' => 'int',
    'not null' => TRUE,
    'unsigned' => TRUE,
    'default' => 0,
    'description' => 'Field added by my_module',
  );
}

function my_module_install() {
  $schema = drupal_get_schema('existing_table');
  db_add_field('existing_table', 'new_field', $schema['fields']['new_field']);
}

Don't forget to call db_drop_field() in your hook_uninstall.

develCuy’s picture

Field schema should be declared in the updated function, not reuse the schema because it might change in future versions, I mean the same field. Say that the field is created in v7001, modified in v7002 and then deleted in v7003. If I'm at v7000, it will try to get the field schema, but current schema will not return the it cause has been removed.

matt2000’s picture

That's a hook_install, not a hook_update_N, so the example is valid, because hook_install only fires once at the initial install, and update hooks are not fired. @develcuy's comments only apply to hook_update_N implementations.

However, the example forgot to include that &$schema needs to be passed into hook_schema_alter by reference.

Rob230’s picture

Thanks for the clarification. Yes I forgot the function parameters. As you say, it should be:

function hook_schema_alter(&$schema)

dpi’s picture

Easy to read over, so emphasis here:

Data truncated and other errors can be resolved by adding 'initial' key to $spec.

dgtlmoon’s picture

Example from redirect module for adding at hook_update

/**
 * Add the {redirect}.uid field.
 */
function redirect_update_2() {
  $field = array(
    'type' => 'int',
    'unsigned' => TRUE,
    'not null' => TRUE,
    'default' => 0,
    'description' => 'The {users}.uid of the user who created the redirect.',
  );
  db_add_field('redirect', 'uid', $field);

  db_update('redirect')
    ->fields(array('uid' => 1))
    ->execute();
}
davidwhthomas’s picture

To add a field, with index information:

  db_add_field('example_table', 'example_field',
    array(
      'type' => 'int',
      'unsigned' => TRUE,
      'description' => 'Example field desc',
    ),
    array(
      'indexes' => array(
        'example_field' => array('example_field')
      ),
    )
  );
rex123’s picture

i have tried adding the column manually in php myadmin but that is not correct way of doing i think

kingandy’s picture

You can do it that way but it's not great - you'll need to do the same thing wherever the module is installed, and also Drupal won't be aware of the new field so might not include it in some operations. The appropriate way to do it within the schema API is to
a) use a hook_install() (PLUS a hook_update_N() if your module is already rolled out and active anywhere) to actually add the field to the database, and
b) use hook_schema_alter() to add the field to Drupal's knowledge of the table.

These should all be done in your module's .install file, which should end up looking something like this:

/**
 * Implements hook_schema_alter().
 */
function mymodule_schema_alter(&$schema) {
  $schema['users']['fields']['mynewfield'] = array(
    'type' => 'int',
    'not null' => TRUE,
    'default' => 0,
  );
}

function mymodule_install() {
  $schema = array();
  // It's OK to reference the schema in a hook_install
  mymodule_schema_alter(&$schema);
  $definition = $schema['users']['fields']['mynewfield'];
  db_add_field('users', 'mynewfield', $definition);
}

function mymodule_update_7101() {
  // It's not OK to reference the schema in an update function, updates must be protected from future changes
  $definition = array(
    'type' => 'int',
    'not null' => TRUE,
    'default' => 0,
  );
  db_add_field('users', 'mynewfield', $definition);
}

function mymodule_uninstall() {
  // Don't forget to clean up after yourself
  db_drop_field('users', 'mynewfield');
}