Я совсем недавно начал работать с 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 и видим, что он стал каким-то другим
Теперь представим ситуацию: в уже существующую модель нам надо добавить пару полей. К примеру, таких:
Создаём миграцию:
Применяем её:
Движимые научным любопытством, смотрим, что нам сгенерил South в 0001_add_download_section.py:
В моём случае напильником пришлось добавить вывод "# coding=utf-8" в начало миграционного скрипта (см. /south/management/commands/startmigration.py, строка 290), иначе он фейлился из-за unicode-строк в нём.
А добавление или удаление полей в уже существующие модели превращается в настоящий 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-строк в нём.