5

I'm working with entities and, in trying to troubleshoot another issue, I noticed that hook_schema() is called twice each time the module is installed. This happened even with a bare bones test module containing only a hook_schema() definition. My questions are:

  • Is it normal for hook_schema() to be called twice on module installation?
  • Why would hook_schema() be called twice on installation?
2
  • Surprisingly interesting question. On the other hand - does it bother you in any way?
    – Mołot
    Commented Jan 13, 2016 at 20:56
  • Molot, it doesn't bother me, so long as I know that it isn't a sign of something wrong. Commented Jan 14, 2016 at 15:51

2 Answers 2

3

It seems to be normal. Looking at the hook_schema documentation, you see that it is invoked in drupal_get_complete_schema() in includes/bootstrap.inc and in drupal_get_schema_unprocessed() in includes/common.inc. The main difference is that the latter does not invoke hook_schema_alter() after the hook_schema is invoked. The first of those functions seems to be called on practically every page load. The second function is called from drupal_install_schema() during the module install process.

Concluding, looking at the code it seems to me that:

  • It is normal
  • It happens because during installation, Drupal needs the un-altered schema definitions
2

Actually, hook_schema() is not just used when a module is installed, and Drupal creates the database tables the module needs. It is also used from other functions or methods that need to know the fields a database table contains. For example, EntityFieldQuery::propertyQuery() and drupal_write_record() use it.

Then, when a module is enabled/installed, Drupal (via module_enable()) invokes hook_schema() twice:

  // Refresh the schema to include it.
  drupal_get_schema(NULL, TRUE);
  // Update the theme registry to include it.
  drupal_theme_rebuild();
  // Clear entity cache.
  entity_info_cache_clear();

  // Now install the module if necessary.
  if (drupal_get_installed_schema_version($module, TRUE) == SCHEMA_UNINSTALLED) {
    drupal_install_schema($module);

    // Set the schema version to the number of the last update provided
    // by the module.
    $versions = drupal_get_schema_versions($module);
    $version = $versions ? max($versions) : SCHEMA_INSTALLED;

    // If the module has no current updates, but has some that were
    // previously removed, set the version to the value of
    // hook_update_last_removed().
    if ($last_removed = module_invoke($module, 'update_last_removed')) {
      $version = max($version, $last_removed);
    }
    drupal_set_installed_schema_version($module, $version);
    // Allow the module to perform install tasks.
    module_invoke($module, 'install');
    // Record the fact that it was installed.
    $modules_installed[] = $module;
    watchdog('system', '%module module installed.', array('%module' => $module), WATCHDOG_INFO);
  }

Your Answer

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

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