What's new? | Help | Directory | Sign in
Google
deseb
Django External Schema Evolution Branch
  
  
  
  
    
Search
for
Updated Jan 03, 2008 by burchik
Labels: Featured
Usage  

Introduction

Using deseb is designed to be very simple. It integrates itself into django automatically, and monitors your models for structural changes. (changes that effect your database schema)

Traditionally with django when these kinds of changes happened, you had one of three options:

  1. lose all your data when django resets your schema
  2. export your data, have django reset your schema, re-import
  3. write your own schema alternation script

The third operation is obviously the safest and most efficient, however it is time consuming and requires extensive knowledge of your particular database backend and SQL. This is what this project automates for you, by comparing your new models with the existing database schema.

It's important to note that no schema generation program can ever be 100% safe and effective. (this includes "syncdb") So it's wise to check the generated SQL before you apply it to your database. However the authors of this program are data-conservative by nature, and every attempt has been made to assure that when the program is the least bit confused as to what it should do, it will do nothing.

Basic Usage

We promised it would be dead simple, didn't we? :)

Assuming you've added "import deseb" to your settings.py, and that you've made a recent change to one of your models (say, add a field) in an app called "myapp", just run the following:

./manage sqlevolve my_app

Assuming it was a field named "newfield" you added to "mymodel", you'll get the following:

BEGIN;
ALTER TABLE `myapp_mymodel` ADD COLUMN `newfield` varchar(200) NOT NULL;
COMMIT;

If you're happy with its work, simply copy/paste it into your database, or pipe it like this:

./manage sqlevolve my_app | mysql mydb

The vast majority of changes can be handled completely automatically like this. However renaming either a field or a model requires one extra step.

Renaming a Field

Add an attribute "aka" to your field definition, so it looks like this:

new_name = models.CharField(maxlength=200, aka='old_name')

Renaming a Model

Add an attribute "aka" to your model's meta definition, so it looks like this:

class NewName(models.Model):
    [...]
    class Meta:
        aka = 'OldName'

And we'll do all the rest.

One more thing: Anywhere you set an aka attribute, you can set it to either a string or a tuple of strings. Use the tuples when you have more than one previous name you want to support migrating from. And if you don't like clutter, when you're sure all your schema's have been updated, feel free to take the 'aka's back out. :)

Fingerprinting

SQL fingerprinting is a way of identifying an existing schema, to later verify its structure. The fingerprints themselves are generated by the sqlfingerprint command, like this:

derek@kaylee:~/projects/deseb/tests$ ./manage.py sqlfingerprint case01_add_field
Notice: Current schema fingerprint for 'case01_add_field' is 'fv1:1742830097' (recognized)

"(recognized)" means that the fingerprint read from the database matches a known fingerprint defined in 'case01_add_field.schema_evolution.mysql_evolutions'.

These are used primarily for managed deployments.


Sign in to add a comment