0

I want to change data-type of a field in for a particular table in database. I want to use hook_schema_alter() to do so. The ALTER query is:

ALTER TABLE `abcd` CHANGE `session_number` `session_number` INT( 255 ) NOT NULL COMMENT 'Session number to get number.'

Is it possible to implement such query using hook ? If yes please guide me. Tonnes of thanx in advance.

2
  • You shouldn't do that in hook_schema_alter(). hook_schema_alter is to alter the schema definition but it won't be able to modify the database for you. You need to implement that in hook_enable() which will invoke during enabling your custom module.
    – Jimmy Ko
    Aug 1, 2016 at 16:24
  • I have multiple instances for same code means same project running for 2 different places . Thats why am thinking to use hook_schema_alter(). Moreover, how to user hook_enable to implement db alteration ? Aug 1, 2016 at 16:31

2 Answers 2

1

As you mentioned you are having single Drupal code base for multiple sites. I assume that you only want one of the sites having schema change. So you need a separate module for altering schema.

You need to implement hook_schema_alter() and hook_enable() in .install file of your custom module.

/**
 * Implements hook_enable().
 */
function mymodule_enable() {
  // other_module is the module name which define the schema of 'abcd' table.
  $schema = drupal_get_schema_unprocessed('other_module', 'abcd');
  db_change_field('abcd', 'session_number', 'session_number', $schema['fields']['session_number']);
}

/**
 * Implements hook_schema_alter().
 */
function mymodule_schema_alter(&$schema) {
  $schema['abcd']['fields']['session_number'] = array(
    'type' => 'int',
    'size' => 'tiny',
    'not null' => TRUE,
    'default' => 0,
    'description' => 'Session number to get number.',
  );
}

Please note that 'size' => 'tiny' means 1 byte size for integer type. More details can be found here.

1
  • 1
    Code is same for multiple sites. I want to run it on each site. Huge thankx... Aug 2, 2016 at 5:01
2

Changes to the schema are typically handled with hook_update_N and you will normally locate this file in the module.install file.

For example with the update from Drupal 6.x-7.x the some of the base permissions were rename:

/**
 * Rename blog and forum permissions to be consistent with other content types.
 */
function system_update_7000() {
  $result = db_query("SELECT rid, perm FROM {permission} ORDER BY rid");
  foreach ($result as $role) {
    $renamed_permission = $role->perm;
    $renamed_permission = preg_replace('/(?<=^|,\ )create\ blog\ entries(?=,|$)/', 'create blog content', $renamed_permission);
    $renamed_permission = preg_replace('/(?<=^|,\ )edit\ own\ blog\ entries(?=,|$)/', 'edit own blog content', $renamed_permission);
    $renamed_permission = preg_replace('/(?<=^|,\ )edit\ any\ blog\ entry(?=,|$)/', 'edit any blog content', $renamed_permission);
    $renamed_permission = preg_replace('/(?<=^|,\ )delete\ own\ blog\ entries(?=,|$)/', 'delete own blog content', $renamed_permission);
    $renamed_permission = preg_replace('/(?<=^|,\ )delete\ any\ blog\ entry(?=,|$)/', 'delete any blog content', $renamed_permission);

    $renamed_permission = preg_replace('/(?<=^|,\ )create\ forum\ topics(?=,|$)/', 'create forum content', $renamed_permission);
    $renamed_permission = preg_replace('/(?<=^|,\ )delete\ any\ forum\ topic(?=,|$)/', 'delete any forum content', $renamed_permission);
    $renamed_permission = preg_replace('/(?<=^|,\ )delete\ own\ forum\ topics(?=,|$)/', 'delete own forum content', $renamed_permission);
    $renamed_permission = preg_replace('/(?<=^|,\ )edit\ any\ forum\ topic(?=,|$)/', 'edit any forum content', $renamed_permission);
    $renamed_permission = preg_replace('/(?<=^|,\ )edit\ own\ forum\ topics(?=,|$)/', 'edit own forum content', $renamed_permission);

    if ($renamed_permission != $role->perm) {
      db_update('permission')
        ->fields(array('perm' => $renamed_permission))
        ->condition('rid', $role->rid)
        ->execute();
    }
  }
}
4
  • This is true for database tables the module itself defines. If a module wants to change the database tables defined from another module, it should implement hook_schema_alter().
    – apaderno
    Aug 1, 2016 at 18:19
  • For my own knowledge going forward, would this hook also by best kept in the module.install file? and how many times will the hook_schema_alter hook run? Aug 2, 2016 at 15:01
  • Drupal looks for hook_schema_alter() in the .install file of the module. It is called every time a module calls drupal_get_schema() and Drupal cache for that has been cleared, for example because a module was disabled or enabled.
    – apaderno
    Aug 2, 2016 at 15:19
  • I think you are correct with the use of hook_schema_alter to manage the changes in $schema, but the actual db_change_field call should be handled within hook_install or hook_update_X as these hooks allow for better deployment management. A module should not have be disabled/enabled for updates/changes take effect. Aug 2, 2016 at 17:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.