Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Updates: hook_update_N

An update is a function that brings an already running site to a new version of the module once: it adds a column to a table, moves data, writes a new setting. While the module is installed nowhere but your computer, you can simply reinstall it. But on a production site reinstalling would delete data — there changes are made with updates.

Where updates are written

In the blog.install file, next to blog_schema(). The function name is blog_update_N, where N is a number. Drupal remembers the number of the last update it ran and runs only those that are greater.

The first update

Let us add a name column to the subscribers table:

// web/modules/custom/blog/blog.install
 
/**
 * Adds the name column to the subscribers table.
 */
function blog_update_10001(): void
{
    $schema = \Drupal::database()->schema();
 
    if (!$schema->fieldExists('blog_subscribers', 'name')) {
        $schema->addField('blog_subscribers', 'name', [
            'type' => 'varchar',
            'length' => 100,
            'not null' => TRUE,
            'default' => '',
        ]);
    }
}

schema() returns the object for changing the database structure. The column description is the same array as in blog_schema(). The comment above the function is required: Drush shows its text as the description of the update.

Running

vendor/bin/drush updatedb

The short form is drush updb. The command shows the list of pending updates with their descriptions and runs them after confirmation. A second run reports that there are no updates: the number 10001 is already recorded as done.

Do not forget the schema

An update changes sites that are already installed. For new installations of the module to get the column at once, add it to blog_schema() too:

// web/modules/custom/blog/blog.install
'fields' => [
    'id' => ['type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE],
    'email' => ['type' => 'varchar', 'length' => 255, 'not null' => TRUE],
    'name' => ['type' => 'varchar', 'length' => 100, 'not null' => TRUE, 'default' => ''],
    'created' => ['type' => 'int', 'not null' => TRUE, 'default' => 0],
],

On a fresh installation only blog_schema() runs, and the updates are treated as already applied.

Numbers

The number is an integer, each next one greater than the previous: 10001, 10002, 10003. By convention it starts with the Drupal version the module is written for: 10 or 11, followed by a three-digit sequence number.

Updating settings

A value is added to configuration the same way:

// web/modules/custom/blog/blog.install
 
/**
 * Adds the show_reading_time setting.
 */
function blog_update_10002(): void
{
    \Drupal::configFactory()
        ->getEditable('blog.settings')
        ->set('show_reading_time', TRUE)
        ->save();
}

The new setting is also added to config/install/blog.settings.yml and to the schema config/schema/blog.schema.yml.

Methods for changing the structure

MethodWhat it does
addField($table, $field, $spec)Adds a column
dropField($table, $field)Removes a column
changeField($table, $field, $new_name, $spec)Changes the name or type of a column
addIndex($table, $name, $fields, $spec)Adds an index
createTable($name, $spec)Creates a table
tableExists($table), fieldExists($table, $field)Check for existence

Updating core and modules

Core and ready-made modules are updated by Composer, and their own update functions are run by the same command:

composer update "drupal/core-*" --with-all-dependencies
vendor/bin/drush updatedb -y
vendor/bin/drush cache:rebuild

Make a database backup before updating: drush sql:dump --result-file=../backup.sql. Security updates are shown on the Reports → Available updates page.

Common mistake

An update that has already run on any site must not be edited: Drupal remembered its number and will not run the changed code. If the function has a bug or one more change is needed, write a new function with the next number. Only an update that has not left your computer yet may be edited.

Thanks for reading!

Donate to the site — we work hard for you.