Main | December 2006 »

November 2006 Archives

November 30, 2006

Subverted Migrations

I got fed up with the lack of best practice for working with Rails migrations across source control branches, so I decided to write a little Rails plugin. Here it is: the first release of Subverted Migrations!

This is a plugin that manages your migration versions across Subversion branches. It has two primary functions:

  • It scans all of your Subversion branches and trunk to find a safe version number when creating migrations.
  • It keeps track (à la svnmerge.py) of which migrations have been applied, and applies new migrations when they are merged back into the branch. (A detailed example exploring this feature is below.)

Warning

Careful, it's alpha! Please back up your schemas and data before trying this. At this time, it is only tested on OS X and PostgreSQL.

Getting It

script/plugin install \
  svn://svn.madriska.com/plugins/subverted_migrations

Example (with Chunky Bacon)

Assume you have trunk and a ChunkyBacon branch (/branches/chunky_bacon). Both
have their latest migration at revision 010.

You create a migration in trunk:

[trunk]$ script/generate migration BoringBacon
    exists  db/migrate
    create  db/migrate/011_boring_bacon.rb

Next, you want to create a migration in branches/chunky_bacon. Without this
plugin, the new migration would have version number 011 and would create a
merge conflict. With the plugin, the version numbers are kept in sync:

[branches/chunky_bacon]$ script/generate migration ExtraCrispy
    exists  db/migrate
    create  db/migrate/012_extra_crispy.rb

The migration scripts should work as usual, but behind the scenes they keep
track of which migrations have been run, à la svnmerge.py. So let's say you
run the migration from the branch:

[branches/chunky_bacon]$ rake db:migrate
Current version: 1-10
Target version: 1-12
== ExtraCrispy: migrating ==================================================
(...)
== ExtraCrispy: migrated (0.0000s) =========================================
Final version: 1-10,12

This indicates that the migrated version contains migrations 1-10 (from
before), as well as the ExtraCrispy revision (12). Once the Rake script detects
that a file matching "db/migrate/011_*" has been added, it will apply that
change as well. So if you merge the BoringBacon change from trunk into the
Chunky Bacon branch, just run "rake db:migrate" and it will pick up the new
change:

[branches/chunky_bacon]$ (svnmerge...)
[branches/chunky_bacon]$ rake db:migrate
Current version: 1-10,12
Target version: 1-12
== BoringBacon: migrating ==================================================
(...)
== BoringBacon: migrated (0.0000s) =========================================
Final version: 1-12

Note that version 11 has been incorporated, and now the version is 1-12.

You may also specify a version string on the command line. It can either be a
series of ranges or numbers separated by commas ("1-6,7,12-42") or a single
number, as before ("12", equivalent to "1-12"). To specify a single revision,
you must express it as a range (to migrate to revision 6 only, specify "6-6").

To back out the BoringBacon change, we would specify the version string that
removes version 11. The plugin includes a Rake task to show the current
version:

[branches/chunky_bacon]$ rake db:version
1-12

We remove 11 from the range and give the new range as an environment variable:

[branches/chunky_bacon]$ rake db:migrate VERSION="1-10,12"
Current version: 1-12
Target version: 1-10,12
== BoringBacon: reverting ==================================================
(...)
== BoringBacon: reverted (0.0000s) =========================================
Final version: 1-10,12

And now the change is backed out.

November 29, 2006

heh

This one's funny.

November 27, 2006

Math is hard.

Following in the footsteps of many wannabe geeks, I have been playing around with machine-learning algorithms for the Netflix Prize. The group that improves Netflix's recommendation algorithm (Cinematch) by 10% wins a cool million. I'm really impressed with some of these teams -- the top competitor has already beaten Cinematch by 5.77%.

My results have been pretty dismal, but not altogether unexpected. This is probably due to the fact that undergrad prob & stats is the limit of my math expertise. Also, I am learning linear algebra as I go. This is in contrast to the leading teams, who have multiple Ph.D.s working full-time on this.

I developed a correlation algorithm for item-based filtering, and it's achieving an RMSE (root mean squared error) of around 1.04. This is only slightly better than just predicting the average score for each movie, and it has a long way to go before it catches up with Cinematch (at 0.95; lower is better). I have a few tweaks in mind, but my cycle time is too high (I'm precomputing correlation tables, so every time I tweak I have something like 8 hours of table computation).

I think I give up.

November 22, 2006

Rails book

It's official -- I'm writing a book on Rails for O'Reilly. It's going to cover mainly metaprogramming, plugins, security, database/deployment issues, performance, and i18n. Look for it around this time next year on your local bookstore shelves.

November 21, 2006

well, it's done

After about 10 hours of just really fun work, I'm 99% done with my switch over from Dreamhost to Oddbeat Inc. for web and application hosting for about 30 clients.

No offense, Dreamhost, but it just wasn't working out. Lighttpd kept paging in and out, and my applications need room to breathe. Maybe next year. In the meantime, I'm putting my money on mongrel.

About November 2006

This page contains all entries posted to Brad Ediger in November 2006. They are listed from oldest to newest.

December 2006 is the next archive.

Many more can be found on the main index page or by looking through the archives.