Rerunning update hooks in D8

Note: there be dragons here... read all the way through before trying this.

When I'm writing an update_hook for a module I'm working on I often need to run it multiple times in order to get it working just right. In Drupal 7 I had a little trick where I would run my updates and then reset the schema version of my module  directly in the database and then run my updates again. I'd rinse and repeat until everything worked as desired.

I've needed to do this in D8 a few times and each time I have forgotten how I did it the last time so I figured if I wrote this post I could always reference it AND I may just help someone else out in the future. The key difference between D7 and D8 in regards to this issue is that the system table no longer exists in Drupal 8. Instead, the schema_version data is now stored (a bit haphasardly) in the key_value table. To see all of your modules (and themes) listed with their current schema versions in D8 you can run this:

SELECT * FROM key_value WHERE collection="system.schema";

You'll notice that the schema version number is serialized so you need to be careful when you update it. If you want to run the mymodule_update_8004() hook over and over (for example) then you just need to run a query like this before you run updates:

UPDATE key_value SET value="i:8003" WHERE collection="system.schema" AND name="mymodule";

Note: I have noticed that some modules have a value of `s:4:"8001"` instead of `i:8001` but it should be safe to use the query above in either case.  

Thanks to @wmostrey for pointing out that you can also do something along these lines to achieve the same result: 

drupal_set_installed_schema_version('my_module', 8005);

Finally, a warning: You should NEVER do this on production sties and you should make sure that you are very familiar with what your update hook actually does before trying this. You need to ask yourself "will I break anything if I run this code over and over again?" There are some sitautions where this could break your site or throw unwanted errors. For example, if your update hook alters a table then running it again will throw an error. If your update hook increments a value, that value will be incremented again and again. Is that safe? Depends on what you are doing.