<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Reliably Broken &#187; migration</title>
	<atom:link href="http://reliablybroken.com/b/tag/migration/feed/" rel="self" type="application/rss+xml" />
	<link>http://reliablybroken.com/b</link>
	<description>It&#039;s a blog: let&#039;s do funch!</description>
	<lastBuildDate>Thu, 01 Dec 2011 21:27:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>First steps with South</title>
		<link>http://reliablybroken.com/b/2009/03/first-steps-with-south/</link>
		<comments>http://reliablybroken.com/b/2009/03/first-steps-with-south/#comments</comments>
		<pubDate>Wed, 04 Mar 2009 21:50:46 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[migration]]></category>
		<category><![CDATA[south]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=52</guid>
		<description><![CDATA[My first time using a schema evolution tool for a Django project, and I like it. I chose South because it had a clear path for devolving a schema and had a database-independent API (I&#8217;ve been testing Postgres with some projects that currently use a MySQL database since we have a Trac installation that uses [...]]]></description>
			<content:encoded><![CDATA[<p>My first time using a schema evolution tool for a <a href="http://www.djangoproject.com/">Django</a> project, and I like it. I chose <a href="http://south.aeracode.org/">South</a> because it had a clear path for devolving a schema and had a database-independent API (I&#8217;ve been testing <a href="http://www.postgresql.org/">Postgres</a> with some projects that currently use a <a href="http://www.mysql.com/">MySQL</a> database since we have a <a href="http://trac.edgewall.org/wiki/DatabaseBackend">Trac installation that uses Postgres</a> anyway).</p>

<p>I have a simple application to store serial numbers and purchasing information for software. It has a <code>License</code> model, but I wanted to add a comment on each license. Following the instructions for <a href="http://south.aeracode.org/wiki/ConvertingAnApp">converting an existing app</a> on the South wiki, here&#8217;s what I did to convert my software license application.</p>

<p>First I added <code>south</code> to <code>INSTALLED_APPS</code> in <code>settings.py</code> and ran <code>manage.py syncdb</code> to install the South application tables for the first time. This was before using South to actually manage any of the evolutions.</p>

<pre><code>% ./manage.py syncdb
Syncing...
Creating table south_migrationhistory

Synced:
 &gt; django.contrib.auth
 &gt; django.contrib.contenttypes
 &gt; django.contrib.sessions
 &gt; django.contrib.sites
 &gt; django.contrib.admin
 &gt; myproject.software
 &gt; south

Not synced (use migrations):
 - 
(use ./manage.py migrate to migrate these)
</code></pre>

<p>Then I created an initial migration for my application. This gives me a migration that matches the existing database schema.</p>

<pre><code>% ./manage.py startmigration software --initial
Creating migrations directory at '/Users/david/myproject/../myproject/software/migrations'...
Creating __init__.py in '/Users/david/myproject/../myproject/software/migrations'...
Created 0001_initial.py.
</code></pre>

<p>The next step was to bring this application under South&#8217;s control. You have to pretend to apply the initial migration (because it already exists in the database), which is done using South&#8217;s <code>--fake</code> switch. I discovered a problem with my use of <code>_</code> in my <code>0001_initial.py</code> migration: the easiest fix was to import it explicitly within the migration (this fix was necessary for the second migration too).</p>

<pre><code>from south.db import db
from django.db import models
from myproject.software.models import *
from django.utils.translation import gettext_lazy as _
</code></pre>

<p>Then I was ready to bring my application under South&#8217;s control.</p>

<pre><code>% ./manage.py migrate software 0001 --fake
 - Soft matched migration 0001 to 0001_initial.
Running migrations for software:
 - Migrating forwards to 0001_initial.
 &gt; software: 0001_initial
   (faked)
</code></pre>

<p>Now I was ready to alter my model definitions and get South to do the tedious work of updating the database schema. I added a new <code>Note</code> model in the application&#8217;s <code>models.py</code> and added a new field to the existing <code>License</code> model.</p>

<pre><code>class License(models.Model):
    """A license for a software title."""
    ...
    department = models.CharField(_("Department"), max_length=100, blank=True)
    ...


class Note(models.Model):
    """A note for a license."""
    license = models.ForeignKey(License, editable=False)
    author = models.CharField(_("author"), max_length=100, editable=False)
    created = models.DateTimeField(auto_now_add=True)
    note = models.TextField(_("note text"))

    def __unicode__(self):
        return self.note

    class Meta:
        ordering = ['-created']
</code></pre>

<p>With those changes I used the <code>startmigration</code> command to generate a migration for the new model and fields.</p>

<pre><code>% ./manage.py startmigration software notes_department --model Note --add-field License.department
Created 0002_notes_department.py.
</code></pre>

<p>(Afterwards I edited the migration to import <code>_</code> as noted above.)</p>

<p>The final step was to use South to apply this migration (and any others) to the database.</p>

<pre><code>% ./manage.py migrate software 
Running migrations for software:
 - Migrating forwards to 0002_notes_department.
 &gt; software: 0002_notes_department
   = ALTER TABLE "software_license" ADD COLUMN "department" varchar(100) NOT NULL; []
   = CREATE TABLE "software_note" ("id" serial NOT NULL PRIMARY KEY, "license_id" integer NOT NULL, "author" varchar(100) NOT NULL, "created" timestamp with time zone NOT NULL, "note" text NOT NULL); []
   = ALTER TABLE "software_note" ADD CONSTRAINT "license_id_refs_id_61c4291d" FOREIGN KEY ("license_id") REFERENCES "software_license" ("id") DEFERRABLE INITIALLY DEFERRED; []
   = CREATE INDEX "software_note_license_id" ON "software_note" ("license_id"); []
 - Sending post_syncdb signal for software: ['Note']
 - Loading initial data for software.
</code></pre>

<p>Sweet!</p>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2009/03/first-steps-with-south/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

