Evolutions - Migrations for Model-Centric Apps
November 24, 2007
There is a project for Django called Evolution, which is conceptually similar to Rails’ Migrations. There are some differences between Evolutions and Migrations, mainly due to the fact that Django is model-centric, meaning that you define the attributes of your models in the code and generate the database from that. Rails, or I guess ActiveRecord more specifically, as you probably know, is the opposite, where you define your database tables and an object model is generated at runtime from the database metadata. So I guess you would call that a database-centric ORM. Here’s their take on the differences:
Isn't this just ActiveRecord::Migration in Python? Superficially, yes, but not really. There is a degree of similarity - the Django Evolution syntax is a DSL for describing the changes that have been made to a model. However, there are also some significant differences. In addition to ActiveRecord::Migration, Django Evolution provides: 1. An audit trail - a permanent archive in the database of the changes that have been applied, and when. 2. An automated hinting scheme. If you don't want to write the migrations yourself, you don't have to. 3. Validation that an evolution script will leave the database in a state consistent with the current model definition. These differences are largely afforded by the model-centric design of Django itself. Whereas a Ruby on Rails model is a description of a database that has been created by hand, Django uses the Python model to creates the database. As a result, the model definition is canonical - not the database. This means that audit, hinting, and verification schemes can use the Django model as a point of reference. A Django Evolution script is much more than just an alternate syntax for SQL ALTER statements - it is an evolution scheme that is bound to the canonical model definition.
The DataMapper project is a model-centric ORM for Ruby apps and as that project continues to grow, their could be some ideas borrowed from Django Evolution, although they do already have their own thing going on with Auto-Migration.
But I’m a Ruby guy, so I’ve got to take one shot at them here :). They say “the Django Evolution syntax is a DSL”. Really?
MUTATIONS = [ AddField('Author', 'location', models.CharField, max_length=100, null=True) ]
I’m sorry, but if that’s a DSL, then what isn’t a DSL? In my opinion, there is too much Python syntax to call that a DSL. It’s a subtle difference but this is a DSL:
add_column :authors, :location, :limit => 100
The question when is it a language specific library and when it is a DSL? Would you call this a DSL?
Mutation m = new AddField("Author", "location", CharField.class); m.setMaxLength(100); m.setAllowNulls(false); Mutations.add(m);