6.x core.php hook_schema_alter(&$schema)
7.x system.api.php hook_schema_alter(&$schema)

Perform alterations to existing database schemas.

When a module modifies the database structure of another module (by changing, adding or removing fields, keys or indexes), it should implement hook_schema_alter() to update the default $schema to take its changes into account.

See hook_schema() for details on the schema definition structure.

Parameters

$schema: Nested array describing the schemas for all modules.

Related topics

1 invocation of hook_schema_alter()
drupal_get_complete_schema in includes/bootstrap.inc
Gets the whole database schema.

File

modules/system/system.api.php, line 3294
Hooks provided by Drupal core and the System module.

Code

function hook_schema_alter(&$schema) {
  // Add field to existing schema.
  $schema['users']['fields']['timezone_id'] = array(
    'type' => 'int',
    'not null' => TRUE,
    'default' => 0,
    'description' => 'Per-user timezone configuration.',
  );
}

Comments

ranavaibhav’s picture

Example of how to use this hook -
http://drupal.org/node/185596#comment-941821

rudiedirkx’s picture

That's a D6 example. It's NOT the code for D7. See the db_add_field.

leonli’s picture

When drupal_get_schema() is called it goes through this sequence:
1) hook_schema()
2)_drupal_schema_initialize() (this DROPs the "description" field.)
3) hook_schema_alter() /* "description" field here will not be dropped. */

This creates inconsistency in the resulting $schema.

Should it be done in this sequence:
1) hook_schema()
2) hook_schema_alter()
3)_drupal_schema_initialize()

SebCorbin’s picture

Note that this hook does not actually change the schema in your database, you'll have to use db_drop_field or db_add_field in a hook_install/hook_uninstall in order to add a field to another table.

n0rtan’s picture

This hook is used to alter the schema when using the drupal_get_schema

JasonSafro’s picture

The following code works for me. It is based on the D6 sample from https://www.drupal.org/node/741568#comment-2715596. My module is called d2d_statistics and I am altering the accesslog table that is created by the core Statistics module.

//-----[ In my .module file ]-----
// Define constants for database elements
define( 'TABLE_ACCESSLOG', 'accesslog' );


/**
 * Implements hook_schema_alter().
 */
function d2d_statistics_schema_alter( &$schema ) {
  $schema[TABLE_ACCESSLOG]['fields']['exit_timestamp'] = array(
    'type' => 'int',
    'unsigned' => TRUE,
    'not null' => TRUE,
    'default' => 0,
    'description' => 'Timestamp of when user left the page.',
  );
}
//-----[ In my .install file ]-----
/**
 * Implementation of hook_install().
 */
function d2d_statistics_install() {
  // Make sure we have access to the hook_schema_alter() from this module
  module_load_include( 'module', 'd2d_statistics', 'd2d_statistics' );

  // Get the schema alterations from this module
  $new_schema = array();
  d2d_statistics_schema_alter( $new_schema );

  // Add fields for each schema change in TABLE_ACCESSLOG
  if( isset($new_schema[TABLE_ACCESSLOG]['fields']) ) :
    foreach( $new_schema[TABLE_ACCESSLOG]['fields'] as $one_field_name => $one_field_spec ) :
      db_add_field( TABLE_ACCESSLOG, $one_field_name, $one_field_spec );
    endforeach;
  endif;
}


/**
 * Implementation of hook_uninstall().
 */
function d2d_statistics_uninstall() {
  // Make sure we have access to the hook_schema_alter() from this module
  module_load_include( 'module', 'd2d_statistics', 'd2d_statistics' );

  // Get the schema alterations from this module
  $new_schema = array();
  d2d_statistics_schema_alter( $new_schema );

  // Remove fields for each schema change in TABLE_ACCESSLOG
  if( isset($new_schema[TABLE_ACCESSLOG]['fields']) ) :
    foreach( $new_schema[TABLE_ACCESSLOG]['fields'] as $one_field_name => $one_field_spec ) :
      db_drop_field( TABLE_ACCESSLOG, $one_field_name );
    endforeach;
  endif;

}