Migrations em Django com South

E quem nunca precisou adicionar ou remover alguma coluna, nas tabelas do seu banco de dados, depois que a aplicação já estava em produção? Os riscos existem (e são altos), e podem ser diminuidos através de processos automatizados.

Em um mundo ideal, o procedimento de deploy (para entregas contínuas) deve ser automatizado. Com o South, “migrar” a estrutura e os dados da sua base de dados para a versão presente em seu novo deploy, é simples, prático e 100% integrado ao Django.

Instalando o South

South é muito, mas muito simples de instalar. Utilizando o pip, basta o seguinte comando para termos os eggs em nosso PYTHONPATH:

$ pip install south

Não podemos esquecer de adicioná-lo ao INSTALLED_APPS do settings.py (afinal, trata-se de uma app Django):

INSTALLED_APPS = (
    'django.contrib.auth',
    ...
    'south',
)

Pronto! Você acabou de ganhar alguns comandos para construir as suas migrations.

Direto para a prática

Sem perder tempo, vamos construir uma app Django para que possamos demonstrar o uso doSouth:

$ python manage.py startapp blog

# settings.py
INSTALLED_APPS = (
    'django.contrib.auth',
    ...
    'south',
    'blog',
)

Vamos criar um modelo bem básico, com alguns campos (posteriormente, incrementaremos esta estrutura):

# blog/models.py
from django.db import models

class Blog(models.Model):
    titulo = models.CharField('Titulo', max_length=100)
    texto = models.TextField('Texto')

Através do comando schemamigration, com parâmetro –-initial, criaremos a nossa primeira migration:

$ python manage.py schemamigration blog --initial

Vale notar que o comando acima não cria nenhuma tabela no banco de dados. O que ele faz é criar um conjunto de instruções que representa este modelo. Na medida que são feitas alterações no modelo, é necessário gerar novas migrations, que serão sempre baseados nas estruturas já criadas.

Por exemplo, vamos de fato criar a tabela blog no banco de dados:

$ python manage.py migrate blog

Running migrations for blog:
 - blog:0001_initial
 - Loading initial data for blog.
 No fixtures found.

Se houvesse alguma fixture, o South faria o insert das informações para você.

A primeira migration foi criada. Como mencionado antes, a partir de agora toda migration criada será baseada na migration “anterior” (podemos deduzir a ordem das migrations através do prefixo numérico, no caso acima, o 0001 indica que esta é a primeira).

Vamos adicionar um campo no modelo (que equivale a uma coluna no banco de dados), para ilustrar a criação de novas migrations:

# blog/models.py
class Blog(models.Model):
    titulo = models.CharField('Titulo', max_length=100)
    resumo = models.TextField('Resumo', blank=True, null=True)
    texto = models.TextField('Texto')

Não é mais necessário o uso do parâmetro -–initial, de agora em diante precisaremos do parâmetro –-auto (que construirá a migration automaticamente, de acordo com a primeira já existente):

$ python manage.py schemamigration blog --auto

 + Added field resumo on blog.Blog
Created 0002_auto__add_field_blog_resumo.py. You can now apply this migration
with: ./manage.py migrate blog

Pronto! Uma nova migration foi criada… e com um nome bem intuitivo (repare no prefixo numérico). Basta darmos a ordem de replicar estas instruções no banco de dados:

$ python manage.py migrate blog

Running migrations for blog:
 - Migrating forwards to 0002_auto__add_field_blog_resumo.
 - blog:0002_auto__add_field_blog_resumo
 - Loading initial data for blog.
No fixtures found.

A nova coluna foi inserida na tabela blog, sem necessitar de nenhuma intervenção manual. Se você ficou curioso para saber como essa “mágica” acontece, basta abrir as migrations e ver que são instruções escritas em Python, que interagem com o banco de dados “por trás” do ORM doDjango.

South possui mais alguns recursos interessantes (como data migrations), que você pode conferir neste tutorial.

Referências

Klaus Peter Laube

Mais artigos deste autor »

Tecnólogo em Análise e Desenvolvimento de Sistemas pelo Centro Universitário de Jaraguá do Sul (UNERJ). Desenvolvedor Web de longa data, apaixonado por Python e defensor dos padrões Web. Escreve quando pode no http://www.klauslaube.com.br.


2 Comentários

Deixe seu comentário

Seu endereço de e-mail não será publicado. Campos com * são obrigatórios!