Django South. Миграция баз данных.
-
Upload
moscowdjango -
Category
Technology
-
view
5.250 -
download
0
Transcript of Django South. Миграция баз данных.
С чем его подают?
Изменения структуры базы данных
Добавление и удаление столбцов
Изменение типа столбца
Реорганизация данных под новую структуру
Pros & Cons
Заводится с полуоборота из коробки
Совместим с большинством моделей
Неимоверно простая
и логичная концепция
В особых случаях требуется ручное вмешательство :(, но редко, к счастью :)
Как начать?
Прописать в INSTALLED_APPS в settings.py:
INSTALLED_APPS = (
…
'south',
)
Установить Через PIP:
$ sudo pip install south
Из исходников:
$ hg clone http://bitbucket.org/andrewgodwin/south/
$ sudo python setup.py install
Переходим к делу
Поле Тип
timestamp DateTimeField
headers BaseDictField
who ForeignKey
text CharField
Поле Тип
timestamp DateTimeField
ip CharField
user_agent CharField
who ForeignKey
text CharField
сlass Comment
До После
BaseDictFieldsrc/home/fields.py:
from django.db import models
# Словарь, к элементам которого можно получать доступ
# как к полям объекта
class BaseDict(dict):
…
# Поле для хранения JSON-объекта.
# В run-time значение поля имеет тип BaseDict
class BaseDictField(models.TextField):
….
Первая миграция~/disqus/src/$ ./manage.py schemamigration home --initial
! Cannot freeze field 'home.comment.headers'
! (this field has class home.fields.BaseDictField)
! South cannot introspect some fields; this is probably because they are custom
! fields. If they worked in 0.6 or below, this is because we have removed the
! models parser (it often broke things).
! To fix this, read http://south.aeracode.org/wiki/MyFieldsDontWork
Ээээ, что это такое?
Custom field не известен South
Надо ему помочь
Первая миграция
src/home/models.py:# Импортируем функцию добавления правил интроспекции
from south.modelsinspector import add_introspection_rules
...
class Comment(models.Model):
…
# Добавляем правило интроспекцииadd_introspection_rules([], ["^home\.fields\.BaseDictField"])
Вторая миграция
~/disqus/src/$ ./manage.py schemamigration home --auto
src/home/models.py:
class Comment(models.Model):
…
ip = models.CharField(max_length=32, blank=True)
user_agent = models.CharField(max_length=256, blank=True)
+ Added field ip on home.Comment
+ Added field user_agent on home.Comment
Created 0002_auto__add_field_comment_ip__add_field_comment_user_agent.py. You can now apply this migration with: ./manage.py migrate home
Третья миграция
~/disqus/src$ ./manage.py datamigration home headers_to_ip_ua
Created 0003_headers_to_ip_ua.py.
./src/home/migrations/0003_headers_to_ip_ua.py:
class Migration(DataMigration):
def forwards(self, orm):
for comment in orm['home.Comment'].objects.all():
comment.ip = comment.headers.REMOTE_ADDR
comment.user_agent = comment.headers.HTTP_USER_AGENT
comment.save()
def backwards(self, orm):
# При попытке откатить возникнет исключение
raise RuntimeError("Cannot reverse this migration.")
Меняем на сервере
Т.к. на сервере уже есть база данных, то надо сделать “фейковую” миграцию, которая ничего не изменяет:
$ ./manage.py migrate home 0001 --fake
Затем применить остальные миграции (0002 и далее):
$ ./manage.py migrate home
Разворачиваем с нуля
Стандарная синхронизация средствами Django:
$ ./manage.py syncdb
Затем последовательно синхронизируем приложения, где есть миграции South:
$ ./manage.py migrate home
Вопросы?
Cпасибо за внимание?
Презентацияhttp://bit.ly/django-meetup-1203-south
Исходники https://github.com/nikolaykhodov/django-meetup-
1203-south