A talk I gave at DjangoCon US 2009
database�migrations,southand�youAndrew�Godwin[email protected]
View Slide
What�are�migrations?http://www.flickr.com/photos/moonjazz/1216783552/
They're�NOT�moving�data�from�one�database�to�another.http://www.flickr.com/photos/shindotv/3835365427/
Better�name:�Schema�Evolution.http://www.flickr.com/photos/fmc550uz/3562899067/
Django�has�nothing�built-in.
++=
++=Migration�1:�Creates�table�AMigration�2:�Creates�table�BMigration�3:�Adds�field�to�A,������������������������creates�t able�CApply�each�in�order,�get�current�schema
One�set�of�migrations�per�app.http://www.flickr.com/photos/dan_h/2517103627/
Apps�aren't�really�independent.http://www.flickr.com/photos/johnbullas/3301805150/
Is�your�app�fresh,�or�old?http://www.flickr.com/photos/matthewfch/536763437/
Fresh?-�Populate�appname/models.py-�Make�your�initial�migration:./manage.py startmigration appname --initial-�Apply�that�migration./manage.py migrate appname
Already�syncdb'd?-�Locally,�run:./manage.py convert_to_south appname-�Commit,�and�then�on�others�do:./manage.py migrate --fake appname 0001(see:�south.aeracode.org/wiki/ConvertingAnApp)
Migrations�are�flexible.http://www.flickr.com/photos/dunechaser/2630434670/
Autodetection./manage.py startmigration \--auto appname added_some_columnUse�the�autodetectorName�of�the�appSuffix�of�the�new�migration
class Migration:def forwards(self, orm):# Adding field 'Adopter.lizard2'db.add_column('southdemo_adopter', 'lizard2',orm['southdemo.adopter:lizard2'])def backwards(self, orm):# Deleting field 'Adopter.lizard2'db.delete_column('southdemo_adopter','lizard2_id')
We�'freeze'�model�definitions.http://www.flickr.com/photos/stuckincustoms/3410783929/
models = {'southdemo.adopter' : {'first_name': ('django.db.models.fields.CharField' ,[],{'max_length': '50'}),'lizard': ('django.db.models.fields.related.ForeignKey' ,[],{'related_name' : "'adopters'",'to': "orm['southdemo.Lizard']"}),...}
We�migrate�data,�too.http://www.flickr.com/photos/ian-s/2152798588/
def forwards(self, orm):for adopter in orm.Adopter.objects.all():try:adopter.first_name, adopter.last_name = \adopter.name.split( " ", 1)except ValueError :adopter.first_name, adopter.last_name = \adopter.name, ""adopter.save()
Roll�your�own�migrations.http://www.flickr.com/photos/thomashawk/93819794/
Unit�test�integration,�if�you�wanthttp://www.flickr.com/photos/cobalt/409924867/
The�Future�World�Of�Tomorrowhttp://www.flickr.com/photos/stuckincustoms/211566219/
Thanks�for�listening.http://www.flickr.com/photos/sovietuk/378834721/http://south.aeracode.orgAndrew�Godwin[email protected]
Thanks�for�listening.http://www.flickr.com/photos/sovietuk/378834721/http://south.aeracode.orgAndrew�Godwin[email protected]@andrewgodwin