22

I'm extending a module I've previously written and it needs some schema changes which I implement in hook_update_N.

I've updated the module's version from 7.x-1.0 to 7.x-1.1 and implemented the foo_update_7100 and it works fine.

The problem is that I've made a mistake inside foo_update_7100 and now that I've fixed it I cannot rerun the 7100 update. I need to create a 7101 one but that doesn't make sense because all my changes are not committed yet.

I've tried reseting the status of the hook_update_n via:

update system set schema_version=-1 where name='foo';

> Query OK, 1 row affected (0.01 sec)
> Rows matched: 1  Changed: 1  Warnings: 0

Then I do drush cc all but drush updatedb -y still gives me "No database updates required".

How can I solve this instead of simply incrementing the hook_update_N number?

2
  • 1
    Try setting it to 0 rather than -1.
    – Andy
    Commented Sep 10, 2012 at 8:22
  • Thanks. That worked. I should have seen the column description which clearly mentions that -1 means that the module is not installed. Feel free to post that as an answer so I can accept.
    – cherouvim
    Commented Sep 10, 2012 at 8:26

5 Answers 5

15

Setting it to 0 should work. system_schema() says the value should be:

-1 if the module is not installed (its tables do not exist); 0 or the largest N of the module's hook_update_N() function that has either been run or existed when the module was first installed.

2
  • 1
    Actually, this would only work if this is the only update hook; typically, this will cause all update hooks to run again. It is safer to set the value to 1 below the number of the update hook you need to rerun (and any hooks with subsequent numbers will run as well).
    – Eelke Blok
    Commented Mar 16, 2017 at 9:57
  • Is there a reason that -1 would show up for a module that Drupal says is enabled?
    – cdmo
    Commented Mar 23, 2017 at 20:35
24

FYI, in Drupal 8, the system table has been removed, and this information is now stored in the key_value table.

UPDATE key_value SET value='i:8000;' WHERE collection = 'system.schema' AND name = 'module_name';

(As noted above, the actual value should be less than the hook_update_N() you want to repeat, but higher than or matching the last update that does not need to be repeated.)

3

I did this so much that I ended up writing a drush module to roll back the update version in the system table. Called "uroll" for update rollback.

https://github.com/danshumaker/drush-uroll

Usage: drush uroll --module=mycustommodule --version=5

It's super simple but I use it all the time. This combined with a database backup reload script allows you to rinse and repeat when writing update functions.

Hopefully helpful to you. Good luck.

4
  • Awesome! Drupal 7 or Drupal 8? Commented Nov 24, 2017 at 12:57
  • 1
    D7 only for now. Commented Nov 24, 2017 at 22:03
  • Its a good one. Helped me. Just for clarification if my hook_update_N is like mymodule_update_7000 then in your drush uroll command for version I can put 0. Am I right ?
    – Austin
    Commented Apr 15, 2018 at 3:31
  • 1
    @Kamal Sorry I should document it better. If the current hook your're writting hook_update_N is at 7300 then you would give uroll --module=mymodule --version=7299 Which sets the sys table at one before yours. Thus on the next dbup your 7300 gets run. So, no, don't just give it the last two digits but the whole number past mymodule_update_ whatever that may be 9123667.. :) @Eelke has a good description in his answer too. Commented Jun 12, 2018 at 13:30
1

For anyone who is still looking for an answer you can achieve this in 3 ways:

  • SQL: UPDATE system SET schema_version = [N*] WHERE name = '[Name of module]';

  • Drush: drush ev "drupal_set_installed_schema_version('[Name of module]', [N*])"

  • Drush uroll drush uroll --module=[Name of module] --version=N*

*N being the update function you want to revert to (i.e the last successful update function)

0

To get your update hook to run again, you should set the schema_version to 1 below the sequence number of your hook.

Technically, anything below the hook you wish to rerun and above the update hook you do not need/want to rerun (but at least 0; -1 means the module is not installed) is OK; if there are no other update hooks, that means that even 0 falls between those boundaries, but in the typical case, update hooks are increased by one, so only going 1 lower is the only safe option if you do not want to run more code than the current highest update hook.

The update process simply checks that value, and sees if there are any update hooks with a higher sequence number. If so, it will run them in sequence. (This also means that the installation process sets the schema version to that corresponding to the highest available update hook; it assumes that upon installation, your module will have a state corresponding to that last update hook).

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.