11

When you create a new table in hook_schema(), should that table be added in a hook_update_N() as well? Or is there some trick, or something I missed, to have databae-updates automatically add tables?

The documentation of hook_update_N() does not explain anything about introducing new tables, whereas the documentation of hook_schema() says:

The tables declared by this hook will be automatically created when the module is first enabled, and removed when the module is uninstalled.

(Highlight is mine)

And if so, how to best avoid duplicating the schema definitions for the new table in both hook_update_N() and hook_schema(). Simply referring to the schema as follows:

 function hook_update_N(&$sandbox) {
   $schema = hook_schema();
   $name = "foo";
   $table = $schema["foo"];
   db_create_table($name, $table);
 }

Seems to work, but on changing the table again, will fail if a user runs the updates and gets to run two or more hook_update_N()s. After all: the first hook_update_N will then already install the correct database and the second hook_update_M() will try to add/change/alter columns that were already up-to-date.

How do you deal with this?

  • Refer to drupal.org/node/150215 for documentation. So basically to add a new table after a module is installed is via hook_update_N but you also add the table definition to the hook_schema for new users or fresh installs. So sum it up if you make any table changes to update the current tables via hook_update_N but you also merge the changes in the hook_schema. – junedkazi Oct 4 '12 at 15:49
  • 1
    So there is no way to avoid violating DRY, it seems. Pity. – berkes Oct 4 '12 at 16:12
  • nothing that I am aware of. But you can write a small function which has the schema definition and call that definition in both the functions. – junedkazi Oct 4 '12 at 16:15
  • @berkes One could define another function that returns the additional schema and refer to it in both the update and install hooks. – user1359 Aug 2 '16 at 19:30
15

So just a copy paste from drupal.org. You also need to add the schema definition to hook_schema.

/**
 * Create new database table {mytable2}.
 */
function mymodule_update_7101() {
  $schema['mytable2'] = array(
     // table definition array goes here
  );
  db_create_table('mytable2', $schema['mytable2']);
}
  • Do you mean that there is no other way then copying the table-definition from hook_schema() into hook_update_N(). In other words: that there is no way to avoid violating DRY? – berkes Oct 4 '12 at 16:13
  • 3
    @berkes spot on...there's a very good explanation why that is here in case you haven't already seen it – Clive Oct 4 '12 at 17:37
  • @Clive That is an awesome example. Never saw it before. +1 – junedkazi Oct 4 '12 at 17:44
  • @junedkazi There's a link to it on the link you provided in your comment ;) – Clive Oct 4 '12 at 17:45
-2

mymodule_update_7101() is good, along with this hook if we add a hook_install() to execute the same while module installation instead of the hook_schema() definition is also works for me.


/**
 * Implements hook_install().
 */
function mymodule_install() {
  // Change the update number accordingly for more updates.
  for ($i = 7101; $i < 7102; $i++) {
    $update_func = 'mymodule_update_' . $i;
    if (function_exists($update_func)) {
      $update_func();
    }
  }
}

  • It is much better Drupal practice to use the API as directed. Use hook_schema() and hook_update_N() directly. One thing that I do is call my module's hook_schema implementation in hook_update_N(), and then run the respective db_* functions. – mradcliffe Dec 27 '16 at 14:23
  • hook_install() should not call any hook_update_N() implementations, for a simply fact: hook_install() is for installing a module for the first time, which means there aren't tables to update. Also, your code would not work for updates that need a batch to run. – kiamlaluno Dec 30 '16 at 7:31
  • This code snippet will be useful, if you are updating the schema and only for deployment purpose. For an existing live system, this cannot be used. – Akhila V Nair Dec 30 '16 at 8:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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