В RoR имеется концепция миграций: все изменения в моделях фиксируются определённым образом, чтобы потом можно было проапдейтить и development и production БД _автоматически_.
Django не умеет синхронизировать изменения моделей с БД (по крайней мере, на момент написания этого текста) :-(
Отсюда проблема - как быть ?
Вот так - Django Evolution.
Как юзать ?
В общем-то, элементарно. Но, имеются тонкости: если у вас ещё не было _ни одного_ syncdb с моделью, то эта система не сработает. Поэтому подключить к проекту на этапе, когда нет ни одной модели (в самом начале проекта), не получится. Я об этом упоминаю отдельно, чтобы вы не наступали на ненужные грабли.
Теперь, по шагам, для нового проекта:
1) создаём какие-то модели (модель)
2) делаем manage.py syncdb
3) забираем Django Evolution из SVN: svn checkout http://django-evolution.googlecode.com/svn/trunk/ django-evolution-read-only
4) копируем подкаталог django_evolution в свой проект (или, если есть возможность, делаем симлинк)
5) в settings.py в INSTALLED_APPS добавляем django_evolution
6) делаем новый подкаталог для всех app, которые в проекте - evolutions, в нём создаём файл "__init__.py"
7) после изменений в модели делаем manage.py syncdb, видим "Project signature has changed - an evolution is required"
8) делаем manage.py evolve --hint, видим что-то вроде этого:
#----- Evolution for website
from django_evolution.mutations import *
from django.db import models
MUTATIONS = [
DeleteField('Poll', 'pub_date')
]
#----------------------
Trial evolution successful.
Run './manage.py evolve --hint --execute' to apply evolution.
9) теперь копируем весь текст между строками с #-----, т.е. в данном случае:
from django_evolution.mutations import *
from django.db import models
MUTATIONS = [
DeleteField('Poll', 'pub_date')
]
в файл с информативным названием(в данном случае удаляется поле pub_date в модели Poll, называем delete_poll_pub_date.py) в каталог evolutions для app, в котором изменения. У меня app называется website, поэтому получается так:
/website
/evolutions
delete_poll_pub_date.py
__init__.py
не забыли создать __init__.py до этого ?
10) теперь добавляем в файл evolutions/__init__.py такую строчку:
SEQUENCE = ['delete_poll_pub_date']
т.е., в файле evolutions/__init__.py задаётся последовательность модификаций БД.
11) пишем
manage.py evolve --execute
выводится вопрос, отвечаем yes (чтобы всё проходило без вопросов, нужно добавить к команде ключ --noinput, но лучше оставить без --noinput, чтобы было похоже на Terminator 3 :-) ).
В результате имеем: Evolution successful. Т.е. прошёл апдейт структуры БД. Если ещё раз набрать manage.py evolve --execute, выведется "No evolution required."
Вот таким образом это всё работает.
Копируем на production все изменения в нашем коде, включая все файлы evolutions, и там запускаем manage.py evolve --execute.
Конечно, это не полный автомат - но согласитесь, намного лучше, чем ничего. Я думаю, что можно усовершенствовать скрипт, чтобы он сам создавал необходимое в evolutions, но самому некогда.
Насчёт багов пока не в курсе, так что про бекапы не забываем :-)
Читаем полную доку либо тут, либо в docs, который пришёл с svn.
Успехов !
четверг, 20 декабря 2007 г.
Миграции в Django
Подписаться на:
Комментарии к сообщению (Atom)
Комментариев нет:
Отправить комментарий