How to access ActiveRecord & Migrations outside of Ruby on Rails

Rails migrations are an extremely handy way of capturing changes to your database and rolling them back if they are incorrect.

Manipulating or querying a database is a pretty useful tool and ActiveRecord turns your tables into objects so I looked into how to access these features outside of a Rails environment.

I wanted to be able to either specify the database connection details directly in the script if I was running it outside of a Rails application, or to be able to bind into the Rails application's database.yml database configuration file.

To run it as a standalone script with the database details described inside the script run:

ruby play_with_the_database.rb
To run it within the context of a Rails application place the script inside a new directory called db/script and run:
ruby play_with_the_database.rb development
If you want to run the above script against the production database run:
ruby play_with_the_database.rb production
I'll show you the ruby code that I came up with and then explain the important bits below.
require 'active_record'
require 'pp'

database_type = ARGV[0]

if database_type.nil?
database_type = 'custom'
database_yaml = <<-YAML
#{database_type}:
adapter: oracle
database: database.andrewbeacock.com/beacock01
username: my_schema
password: my_schema
YAML
else
# if you have a Rails project then place your scripts in db/script
database_yaml = IO.read('../../config/database.yml')
end

class MyTable < ActiveRecord::Base; set_table_name :my_table; end

class Script < ActiveRecord::Migration
def self.run
execute('update my_table set updated = true')
pp MyTable.find(:all)
end
end

databases = YAML::load(database_yaml)
ActiveRecord::Base.establish_connection(databases[database_type])
Script.run
  • database_type - this is the RAILS_ENV that you want to run the database script against if you are running within a Rails application, it's empty at the start of the script and set to the value that you pass as the first argument on the command line. If an argument is present it looks up that value in the database.yml file otherwise it uses the inlined database connection details within the script.

  • class MyTable - any ActiveRecord object definitions go here allowing you to map objects to tables.

  • def self.run - Place the guts of your database script within this method so that it has access to all the ActiveRecord objects as well as any methods that migrations have access to (such as execute, create_table, add_column, remove_index, etc.).
This script was spawned from two things, a requirement to change the values in a database table without it being a fully tracked migration and a post on Dave Thomas's blog regarding Migrations Outside Rails.

Enjoy!

Technorati Tags: , , , , , ,

htop - a great alternative to top for Ubuntu Linux

I colleague recommended that I install htop the other day. It's an alternative to top which offers colour (ooh), a tree sort view (aah), and the ability to kill off processes within htop itself (very cool).

To install it, simply run:

sudo aptitude install htop
And to run it, simply type:
htop
This is what it looks like running (with the tree view selected):



And here are some of the help options:



Technorati Tags: , , , , ,

Upgrading to Ubuntu 7.10 (Gutsy Gibbon) causes snmpd errors

When Gutsy Gibbon was released back in October I was quick to upgrade my home Ubuntu server to this new release. The upgrade went smoothly apart from one failure - a strange error message when upgrading the SNMP support:

Starting network management services:invoke-rc.d: initscript snmpd, action "start" failed.
dpkg: error processing snmpd (--configure):
subprocess post-installation script returned error exit status 1
I didn't understand the error message and googling for it at the time brought up no solutions. I checked and found that snmpd was running successfully and all appeared fine. I recently applied some more updates and received the same error message so I investigated it again.

This time I found the reason, the SNMP package upgrade scripts don't stop snmpd before they perform the upgrade, so you need to stop snmpd before you update.

This is how I did it:
$ sudo /etc/init.d/snmpd stop
Stopping network management services: snmpd snmptrapd.
$ sudo dpkg --configure -a
Setting up snmpd (5.3.1-6ubuntu2) ...
Starting network management services: snmpd.
That's it, all updated and no errors, I do hope that the installation scripts get fixed for this soon...

Technorati Tags: , , , , ,

How to rollback Rails database migrations

When you perform database migrations in Rails you use the following command:

rake db:migrate
If you want to roll back your change to need need to find out what version your database is currently at and then roll back to a previous version:
rake db:migrate VERSION=<version to roll back to>
I've never liked this way to roll back, seems to much like hard work to me so I found a migration rollback script on the programmingishard site and simplified so that it only rollback by one version:
namespace :db do
  namespace :migrate do
    desc "Rollback the database schema to the previous version"
    task :rollback => :environment do
      previous_version = ActiveRecord::Migrator.current_version.to_i - 1
      ActiveRecord::Migrator.migrate("db/migrate/", previous_version)
      puts "Schema rolled back to previous verison (#{previous_version})."
    end
  end
end
To use this scriptlet, copy and paste the code into a file called db_rollback.rake and place it the lib/tasks directory within your Rails application.

To use it to roll back your most recent migration simply run:
rake db:migrate:rollback
Technorati Tags: , , , , , , ,