Drupal and Drush: Updating the database from the command-line
| drupalSo now that we’re doing all our configuration changes in source code, it makes sense to automate database updates as much as I can. Here’s something I’ve added to drush_tools so that I can run all the schema changes from the command-line:
function drush_tools_update($command = '') { ob_start(); require_once 'includes/install.inc'; require_once 'update.php'; $ret = ob_get_contents(); drupal_load_updates(); ob_end_clean(); $list = module_list(); $update_list = array(); foreach ($list as $module) { $updates = drupal_get_schema_versions($module); if ($updates !== FALSE) { $latest = 0; $base = drupal_get_installed_schema_version($module); foreach ($updates as $update) { if ($update > $base) { if ($update > $latest) { $latest = $update; } $update_list[$module][] = $update; } } if ($latest) { sort($update_list[$module]); printf("%-30s %5d -> %5d (%s)\n", $module, $base, $latest, join(', ', $update_list[$module])); } else { printf("%-30s %5d\n", $module, $base); } } } if (count($update_list) == 0) return; if ($command != 'force' && !drush_confirm(t('Do you really want to continue?'))) { drush_die('Aborting.'); } ob_start(); foreach ($update_list as $module => $versions) { foreach ($versions as $v) { print "Running " . $module . "_update_" . $v . "\n"; update_data($module, $v); } } $updates = ob_get_contents(); cache_clear_all('*', 'cache', TRUE); cache_clear_all('*', 'cache_page', TRUE); cache_clear_all('*', 'cache_menu', TRUE); cache_clear_all('*', 'cache_filter', TRUE); drupal_clear_css_cache(); ob_end_clean(); $output = ''; if (!empty($_SESSION['update_results'])) { $output .= "The following queries were executed:\n"; foreach ($_SESSION['update_results'] as $module => $updates) { $output .= "\n" . $module . "\n--------------------------\n"; foreach ($updates as $number => $queries) { $output .= 'Update #'. $number . ":\n"; foreach ($queries as $query) { if ($query['success']) { $output .= "SUCCESS: " . $query['query'] . "\n"; } else { $output .= "FAILURE: " . $query['query'] . "\n"; } } if (!count($queries)) { $output .= "No queries\n"; } } } $output .= "\n"; print $output; unset($_SESSION['update_results']); } }
7 comments
Jason
2008-09-16T16:01:05ZThanks for this, I've wondered about how to do schema updates without having to switch to my browser, can't wait to try it out!
Anonymouis
2008-09-16T18:28:43ZThis does not support multi-part updates.
greggles
2008-09-16T18:36:09ZThis is great news. Thanks for providing the code.
There is an issue for this in the Drush issue queue http://drupal.org/node/194107
Could you please post this as a patch to that? http://drupal.org/patch/create shows the style for Drupal patches.
Thanks!
Moshe Weitzman
2008-09-18T20:31:29ZCool - but it does not handle batch API style update. See http://cvs.drupal.org/viewv... for an example (look for 'sandbox'). yched made same comment at http://drupal.org/node/2330...
Christian Roy
2009-01-16T20:19:57ZThis code that Sacha wrote is for Drupal 5 only.
It is my understanding that the batch api was introduced in drupal 6.
I posted Sacha's patch into the drush project for drush-1.4-5.x
http://drupal.org/node/1941...
Since they are already working on a D6 and D7 version as a stand alone shell script, maybe this patch is not needed/wanted?
Sacha Chua
2009-01-16T23:04:33ZOh, that would be sweet! =D Even better way to do it.
Andreas Rydberg
2009-01-30T16:33:17ZHi Sacha.
Thank you for you code. You seem to have inspired a lot of people with this, includeing me. I've used parts of you code to create a drush module for Drupal 6.x, which I've proposed to the drush-devs.
Here is the link: http://drupal.org/node/366779