Same name and namespace in other branches
  1. 10 core/lib/Drupal/Core/Extension/module.api.php \hook_update_N()
  2. 4.7.x developer/hooks/install.php \hook_update_N()
  3. 6.x developer/hooks/install.php \hook_update_N()
  4. 7.x modules/system/system.api.php \hook_update_N()
  5. 8.9.x core/lib/Drupal/Core/Extension/module.api.php \hook_update_N()
  6. 9 core/lib/Drupal/Core/Extension/module.api.php \hook_update_N()

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
    • MySQL: ALTER TABLE {$table} DROP 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' => "''"));

Return value

An array with the results of the calls to update_sql().

Related topics

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

blogapi_update_5000 in modules/blogapi/blogapi.install
Add blogapi_files table to enable size restriction for BlogAPI file uploads.
comment_update_1 in modules/comment/comment.install
Changed node_comment_statistics to use node->changed to avoid future timestamps.
locale_update_1 in modules/locale/locale.install
Neutralize unsafe language names in the database.
nodeapi_example_update_1 in developer/examples/nodeapi_example.install
node_type_update_nodes in modules/node/node.module
Updates all nodes of one type to be of another type.

... See full list

File

developer/hooks/install.php, line 201
Documentation for the installation and update system.

Code

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,
      ));
      break;
    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");
      break;
  }
  return $ret;
}