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

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

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

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

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

Avatar for Moscow Python Meetup

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