time

Миграция моделей и данных в Django

django-south.png

Always, always, backup your database before doing any kind of potentially destructive migration. One time, it will go wrong.
(из south документации)

South привносит в django возможность миграции структуры и данных модели. На практике это означает, что если мы что-то поменяли в модели (добавили/удалили поле) то south сам увидит изменения и создаст инструкции для внесения изменений в БД, которые останется только применить на всех экземплярах приложения.

Основные особенности, которые отмечают разработчики:

  • отслеживание изменений в модели и создание миграций
  • независимость от движков БД (заявлена поддержка 5 разных типов БД)
  • создание миграций только для выбранного приложения (application)
  • сообщение о возможных конфликтах при комите миграций от других разработчиков

Ставим последнею версию South

pip install South

Добавляем south в INSTALLED_APPS и делаем syncdb.

Создадим точку отсчета миграций для приложения foo и применим их

./manage.py schemamigration foo --initial
./manage.py migrate foo

Добавим новое поле в модель foo и укажем south на изменения

./manage.py schemamigration foo --auto

South создаст миграцию в папке foo/migrations (путь можно поменять в настройках south, переменная SOUTH_MIGRATION_MODULES), дав произвольное имя для файла. Внутри py-файла с миграцией есть класс Migration с двумя методами: forwards, который отвечает за выполняемые инструкции при выполнении команды migrate, и метод backwards - отвечающий за откаты при желании отменить миграцию.

Просмотр списка миграций

./manage.py migrate --list

звездочкой отмечены те миграции, что уже применены.

Применим новые изменения в модели:

./manage.py migrate foo

Кроме миграции структуры модели возможна миграция и данных. Используется, например, для изменения данных в модели для соответствия новой структуре.

Создаем заготовку foo_datamigration_0 для новой миграции данных:

./manage.py datamigration foo foo_datamigration_0

Правим нашу заготовку для миграции данных, для этого в методе forwards(self, orm) добавляем действия для манипуляциии над данными, в передаваемом параметре orm находится уже хорошо знакомый django orm.

def forwards(self, orm):
    for foo in orm.Foo.objects.all():
        foo.title = "new title %d" % random.randrange(1,100)
        foo.save()

South также может отобразить графически процес миграции, начиная с самого начала.

./manage.py graphmigrations | dot -Tpng -omigrations.png

При запуске тестов может появится ошибка: django.db.utils.DatabaseError: no such table: south_migrationhistory, что бы отключить south при прогонке тестов добавляем в settings.py

SOUTH_TESTS_MIGRATE = False 

Дополнительное чтиво:

blog comments powered by Disqus