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

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

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)) {

  • 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.
    – apaderno
    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. 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.