Открыть список
Как стать автором
Обновить

South — новый клёвый syncdb

Django
Я совсем недавно начал работать с Django и меня практически сразу же взбесила ущербная команда syncdb, которая ничего толком не синхронизирует, умеет лишь создавать таблицы для новых моделей.

А добавление или удаление полей в уже существующие модели превращается в настоящий pain in ass — приходится «подсматривать» за тем, как ORM создала бы таблицы заново (manage.py sqlall) и вручную делать ALTER TABLE для изменившихся столбцов таблиц.

То есть, ORM в Django так или иначе предполагает активный трах с SQL shell, потому что в процессе прототипирования эти поля в моделях изменяются просто пачками.

Погуглив, я нашел несколько способов автоматизации изменения схемы БД и в итоге остановился на South. Эта утилита автоматизирует процесс db schema migration. (а название утилиты, насколько я понял, обыгрывает термин «миграция» — ведь зимой все птицы летят на йух :)).

Я выбрал South из-за того, что оно хранит историю миграций и можно делать undo/redo, а так же корректировать код миграции руками.

Полный туториал можно почитать здесь: south.aeracode.org/wiki/Tutorial, я лишь вкратце поясню, как оно работает.


Установка


1. Сливаем svn'ом код утилиты отсюда: https://svn.aeracode.org/svn/south/trunk

2. Кладем его в python/lib/site-packages или еще куда-нибудь, где его будет видно

3. В settings.INSTALLED_APPS добавляем 'south'

4. Делаем привычный manage.py syncdb и видим, что он стал каким-то другим


Использование


Теперь представим ситуацию: в уже существующую модель нам надо добавить пару полей. К примеру, таких:

class CompanyProduct (models.Model):

# .. бла-бла, какие-то старые поля ..

download_url = models.URLField (
u'Ссылка для скачивания',
blank = True, null = True)

system_requirements = models.TextField (
u'Системные требования',
blank = True, null = True)


* This source code was highlighted with Source Code Highlighter.


Создаём миграцию:

python manage.py startmigration [имя_вашего_app] add_download_section
--add-field CompanyProduct.download_url
--add-field CompanyProduct.system_requirements

Creating __init__.py in '[path_to_app]\migrations'...
Created 0001_add_download_section.py.


Применяем её:

python manage.py migrate [имя_вашего_app]

Running migrations for [имя_вашего_app]:
- Migrating forwards to 0001_add_download_section.
> [имя_вашего_app]: 0001_add_download_section
= ALTER TABLE "products" ADD COLUMN "download_url" varchar(200) NULL; []
= ALTER TABLE "products" ADD COLUMN "system_requirements" text NULL; []
- Loading initial data for [имя_вашего_app].


Движимые научным любопытством, смотрим, что нам сгенерил South в 0001_add_download_section.py:

from south.db import db
from django.db import models
from [имя_вашего_app].models import *

class Migration:

def forwards(self):

# Adding field 'CompanyProduct.download_url'
db.add_column('products', 'download_url',
models.URLField (u'Ссылка для скачивания', blank = True, null = True))

# Adding field 'CompanyProduct.system_requirements'
db.add_column('products', 'system_requirements',
models.TextField (u'Системные требования', blank = True, null = True))


def backwards(self):

# Deleting field 'CompanyProduct.download_url'
db.delete_column('products', 'download_url')

# Deleting field 'CompanyProduct.system_requirements'
db.delete_column('products', 'system_requirements')



Косяк


В моём случае напильником пришлось добавить вывод "# coding=utf-8" в начало миграционного скрипта (см. /south/management/commands/startmigration.py, строка 290), иначе он фейлился из-за unicode-строк в нём.
Теги:djangosouthsyncdbмиграцияSQLORM
Хабы: Django
Всего голосов 35: ↑34 и ↓1 +33
Просмотры24.3K

Комментарии 34

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Похожие публикации

Junior+/Middle Django developer
от 80 000 до 100 000 ₽Magnum Hunt Executive SearchМосква
Senior Backend Engineer (Python, Django)
от 2 800 до 3 500 $AppboxoАлматы
Python developer (django)
от 120 000 до 220 000 ₽Федя и СаматМожно удаленно
Разработчик Python (Django)
от 100 000 до 160 000 ₽JuntoМоскваМожно удаленно
Backend Python/Django
от 2 500 до 3 500 $Borderless360Можно удаленно

Лучшие публикации за сутки