Drupal and Drush: Updating the database from the command-line
Posted on September 16th, 2008 by Sacha Chua
So 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']);
}
}
Save to - del.icio.us
- Digg it
- reddit
- StumbleUpon
Thanks 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!
This does not support multi-part updates.
This 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!
Cool - but it does not handle batch API style update. See http://cvs.drupal.org/viewvc.py/drupal/contributions/docs/developer/examples/batch_example.install?revision=1.3&view=markup for an example (look for 'sandbox'). yched made same comment at http://drupal.org/node/233091#comment-992365