Slide 1

Slide 1 text

Django South Миграция баз данных Николай Ходов [email protected]

Slide 2

Slide 2 text

С чем его подают? Изменения структуры базы данных  Добавление и удаление столбцов  Изменение типа столбца Реорганизация данных под новую структуру

Slide 3

Slide 3 text

Pros & Cons  Заводится с полуоборота из коробки  Совместим с большинством моделей  Неимоверно простая и логичная концепция  В особых случаях требуется ручное вмешательство :(, но редко, к счастью :)

Slide 4

Slide 4 text

Как начать? Прописать в INSTALLED_APPS в settings.py: INSTALLED_APPS = ( … 'south', ) Установить  Через PIP: − $ sudo pip install south  Из исходников: − $ hg clone http://bitbucket.org/andrewgodwin/south/ − $ sudo python setup.py install

Slide 5

Slide 5 text

Переходим к делу Поле Тип timestamp DateTimeField headers BaseDictField who ForeignKey text CharField Поле Тип timestamp DateTimeField ip CharField user_agent CharField who ForeignKey text CharField сlass Comment До После

Slide 6

Slide 6 text

BaseDictField src/home/fields.py: from django.db import models # Словарь, к элементам которого можно получать доступ # как к полям объекта class BaseDict(dict): … # Поле для хранения JSON-объекта. # В run-time значение поля имеет тип BaseDict class BaseDictField(models.TextField): ….

Slide 7

Slide 7 text

Первая миграция ~/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 Надо ему помочь

Slide 8

Slide 8 text

Первая миграция src/home/models.py: # Импортируем функцию добавления правил интроспекции from south.modelsinspector import add_introspection_rules ... class Comment(models.Model): … # Добавляем правило интроспекции add_introspection_rules([], ["^home\.fields\.BaseDictField"])

Slide 9

Slide 9 text

Вторая миграция ~/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

Slide 10

Slide 10 text

Третья миграция ~/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()

Slide 11

Slide 11 text

Меняем на сервере Т.к. на сервере уже есть база данных, то надо сделать “фейковую” миграцию, которая ничего не изменяет: $ ./manage.py migrate home 0001 --fake Затем применить остальные миграции (0002 и далее): $ ./manage.py migrate home

Slide 12

Slide 12 text

Разворачиваем с нуля Стандарная синхронизация средствами Django: $ ./manage.py syncdb Затем последовательно синхронизируем приложения, где есть миграции South: $ ./manage.py migrate home

Slide 13

Slide 13 text

Вопросы? Cпасибо за внимание? Презентация http://bit.ly/django-meetup-1203-south Исходники https://github.com/nikolaykhodov/django-meetup- 1203-south