8.5.x module.api.php hook_update_N(&$sandbox)
8.0.x module.api.php hook_update_N(&$sandbox)
8.1.x module.api.php hook_update_N(&$sandbox)
8.2.x module.api.php hook_update_N(&$sandbox)
8.3.x module.api.php hook_update_N(&$sandbox)
8.4.x module.api.php hook_update_N(&$sandbox)
8.6.x module.api.php hook_update_N(&$sandbox)
4.7.x install.php hook_update_N()
5.x install.php hook_update_N()
6.x install.php hook_update_N(&$sandbox)
7.x system.api.php hook_update_N(&$sandbox)

Perform a single update. For each patch which requires a database change add a new hook_update_N() which will be called by update.php.

The database updates are numbered sequentially starting with 1 in each module. The first is mymodule_update_1().

A good rule of thumb is to remove updates older than two major releases of Drupal. Never renumber update functions.

Whenever possible implement both PostgreSQL and MySQL at the same time. If PostgreSQL updates are added later, add a new update function which only does the PostgreSQL update. Be sure to use comments to describe which updates are the same if they do get separated.

Implementations of this hook should be placed in a mymodule.install file in the same directory as mymodule.module. Drupal core's updates are implemented using the system module as a name and stored in database/updates.inc.

The following examples serve as a quick guide to MySQL to PostgreSQL conversion. Usually (but not always!) you will use following SQL statements:

  • Adding a key (an index)

    • MySQL: ALTER TABLE {$table} ADD KEY $column ($column)
    • PostgreSQL: CREATE INDEX {$table}_$column_idx ON {$table}($column) // Please note the _idx "extension"
  • Adding a primary key
    • MySQL: ALTER TABLE {$table} ADD PRIMARY KEY $column ($column)
    • PostgreSQL: ALTER TABLE {$table} ADD PRIMARY KEY ($column)
  • Dropping a primary key
    • PostgreSQL:ALTER TABLE {$table} DROP CONSTRAINT {$table}_pkey
  • Dropping a column
    • MySQL: ALTER TABLE {$table} DROP $column
    • Postgres: ALTER TABLE {$table} DROP $column
  • Dropping an index
    • MySQL: ALTER TABLE {$table} DROP INDEX $index
    • Postgres:
      • DROP INDEX {$table}_$column_idx // When index was defined by CREATE INDEX
      • ALTER TABLE {$table} DROP CONSTRAINT {$table}_$column_key // In case of UNIQUE($column)
  • Adding a column
    • MySQL: $ret = update_sql("ALTER TABLE {vocabulary} ADD tags tinyint(3) unsigned default '0' NOT NULL");
    • Postgres: db_add_column($ret, 'vocabulary', 'tags', 'smallint', array('default' => 0, 'not null' => TRUE));
  • Changing a column
    • MySQL: $ret[] = update_sql("ALTER TABLE {locales_source} CHANGE location location varchar(255) NOT NULL default ''");
    • Postgres: db_change_column($ret, 'locales_source', 'location', 'location', 'varchar(255)', array('not null' => TRUE, 'default' => "''"));

Related topics

81 functions implement hook_update_N()

Note: this list is generated by pattern matching, so it may include some functions that are not actually implementations of this hook.

node_update_index in modules/node.module
Implementation of hook_update_index().
node_update_shutdown in modules/node.module
shutdown function to make sure we always mark the last node processed.
search_update_totals in modules/search.module
This function is called on shutdown to ensure that search_total is always up to date (even if cron times out or otherwise fails).
system_update_110 in database/updates.inc
system_update_111 in database/updates.inc

... See full list


developer/hooks/install.php, line 110
Documentation for the update system.


function hook_update_N() {
  $ret = array();
  switch ($GLOBALS['db_type']) {
    case 'pgsql':
      db_add_column($ret, 'contact', 'weight', 'smallint', array(
        'not null' => TRUE,
        'default' => 0,
      db_add_column($ret, 'contact', 'selected', 'smallint', array(
        'not null' => TRUE,
        'default' => 0,
    case 'mysql':
    case 'mysqli':
      $ret[] = update_sql("ALTER TABLE {contact} ADD COLUMN weight tinyint(3) NOT NULL DEFAULT 0");
      $ret[] = update_sql("ALTER TABLE {contact} ADD COLUMN selected tinyint(1) NOT NULL DEFAULT 0");
  return $ret;