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
This 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/194107#comment-1204613
Since they are already working on a D6 and D7 version as a stand alone shell script, maybe this patch is not needed/wanted?
Oh, that would be sweet! =D Even better way to do it.
Hi 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