Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Django South: Миграция баз данных

Django South: Миграция баз данных

Николай Ходов

На комплексном примере показывается, как производить миграции структуры БД и миграции данных. Неплохое введение для новичков, чтобы начать погружение в тему миграций, которую Django пока что обходит стороной.

Moscow Python Meetup

March 01, 2012
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

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

    и удаление столбцов  Изменение типа столбца Реорганизация данных под новую структуру
  2. Pros & Cons  Заводится с полуоборота из коробки 

    Совместим с большинством моделей  Неимоверно простая и логичная концепция  В особых случаях требуется ручное вмешательство :(, но редко, к счастью :)
  3. Как начать? Прописать в INSTALLED_APPS в settings.py: INSTALLED_APPS = (

    … 'south', ) Установить  Через PIP: − $ sudo pip install south  Из исходников: − $ hg clone http://bitbucket.org/andrewgodwin/south/ − $ sudo python setup.py install
  4. Переходим к делу Поле Тип timestamp DateTimeField headers BaseDictField who

    ForeignKey text CharField Поле Тип timestamp DateTimeField ip CharField user_agent CharField who ForeignKey text CharField сlass Comment До После
  5. BaseDictField src/home/fields.py: from django.db import models # Словарь, к элементам

    которого можно получать доступ # как к полям объекта class BaseDict(dict): … # Поле для хранения JSON-объекта. # В run-time значение поля имеет тип BaseDict class BaseDictField(models.TextField): ….
  6. Первая миграция ~/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 Надо ему помочь
  7. Первая миграция src/home/models.py: # Импортируем функцию добавления правил интроспекции from

    south.modelsinspector import add_introspection_rules ... class Comment(models.Model): … # Добавляем правило интроспекции add_introspection_rules([], ["^home\.fields\.BaseDictField"])
  8. Вторая миграция ~/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
  9. Третья миграция ~/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()
  10. Меняем на сервере Т.к. на сервере уже есть база данных,

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

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