Nashvegas: A Simple Django Migration Tool
Introduction
Back in July I discussed how I built a tool to help manage database changes across a team and through deployment for our Django based project.
And yes, I am aware of other approaches/projects tackling this same problem. None of them seemed to work how I wanted them to as they all seemed to focus on trying to keep you
from writing the raw sql yourself.
I am comfortable with writing SQL and for something that will execute automatically against production databases, I prefer to have that control in knowing exactly what will get executed. Yes, many of these tools have options to allow me to preview the generated SQL, but it still gave me the feeling of being boxed in.
For your reference, here are the ones I reviewed:

So I abstracted out the script and it's assumptions about our environment to function as a management command in a stand alone reusable app.
My Approach
It's extremely simple and is based purely on executing SQL statements in order based on it's file naming scheme. Basically, you create a folder somewhere in your project -- I call mine "db". Within this folder you put the changes to the database into SQL scripts named using a convention that will list them in order. I use:
YYYYMMDD-##.sql
This allows members of the team to know at a glance when the script was created and gives some reasonable avoidance of name collisions. There have been instances where we've had a name collision (I try to push in a commit that has 20090224-01.sql added in my commit index and it already exists in the remote branch, so I just move the file to 20090224-02.sql, commit, pull and then push again).
To sync up your database with changes from the rest of the team you would just execute:
./manage.py upgradedb --execute
If you wanted to just see the output that will be executed you can run it without the --execute flag to just print out the contents to standard output:
./manage.py upgradedb
By default, it looks for a folder with scripts in your current working directory called "db". If your scripts are located elsewhere, just use the --path parameter:
./manage.py upgradedb --execute --path /path/to/db/folder
Where to Get It
I have released v0.1 of the app as it has the bare minimum now to be usable. But there are handful of
other additions that I think will make it generally more useful. I do welcome any and all feedback on
this project, but want to restate this isn't meant as a replacement or competition for the other migration
projects listed above. I have reviewed all of them, and none fit how I preferred to work.
I also welcome any patches, so head over to the project and fork it!
I figured since they really didn't fit my needs and/or what I wanted to do, then there might be others in the same boat and might find what I have done to be useful.
Commentary
I'm normally against many projects tackling the same problem instead of people working together on a single solution. However, it seems that there's no clear consensus about how this should be done, and the existing solutions I've tried have also felt bad to me, so it's nice to see another attempt -- especially one oriented at teams.
My main concern with these things though, is what happens when you're working with a DVCS? Horrible visions of conflicting upgrades spring to mind.
Lee:
Reducing conflict in a DVCS is why we have chosen to use a naming scheme that involves the days date following by an index number.
It all comes down to what naming convention you adopt as a team to avoid the collisions. One solution would be for each team member to prefix his/her script with their username (e.g. paltman-20090224-01.sql). However, you'd want to be careful if you did that that you were dependent on a DDL change from another team member who's username came after your alphabetically.
I have found it very rare that we have collisions with the date based naming, however, I am sure that breaks down at some level as the team size grows. That being said, as the team size grows, I think it is important to funnel database schema changes through a small core group for this very purpose.
I worked on a team of 12 at one point and every single database change we made funneled through one person, who would chain together the scripts in a very similar fashion to what I am doing with this project (I borrow heavily from what I saw him doing) and it worked out very well.
Bottom line, every situation/team/project is different.
This sounds pretty close to what Dbmigration does. Does your tool keep track of which migrations have been applied?
http://www.aswmc.com/dbmigration/ though this is dead at the moment, Google cache version is http://74.125.95.132/search?q=cache:Qq81S2uDm-4J:www.aswmc.com/dbmigration/+dbmigration&hl=en&ct=clnk&cd=1&gl=us&client=firefox-a
Kent
Kent:
No, I hadn't heard of
dbmigrations. Thanks for the cache link.It does indeed sound similar, I'll read up on it more. Might be able to find some good ideas.
Yes, nashvegas does keep track of what's been executed in a table it creates on the initial run in your database called
versions.Thanks!