Django — один из самых популярных фреймворков для python. Он поддерживает автоматическое создание баз данных для ваших приложений. Достаточно выполнить
python manage.py syncdb
и в указанной вами базе данных будут созданы все таблицы, соответствующие определенным в models.py классам моделей.
У встроенной syncdb есть один недостаток — он не умеет менять структуру базы данных при изменении модели.
На практике это означает, что при добавлении пары элементов данных в описание вашей модели вам нужно будет вручную менять структуру таблиц в БД, либо создавать базу данных заново, теряя все данные.
На помощь приходит такой инструмент, как South.
Как работает Django South
Изменение базы с помощью south происходит в два этапа
- South определяет, что нужно изменить и создает файл-миграцию
- Миграция применяется к базе данных, отражая изменения моделей
Как это выглядит на практике
Сперва нужно создать начальную миграцию:
python manage.py schemamigration <имя_приложения> --initial
Это сохранит для дальнейшей работы south начальную схему базы данных.
Для создания таблиц в базе для приложения с имеющимися миграциями, после установки south недостаточно выполнить syncdb — нужно выполнить сами миграции:
python manage.py migrate <имя_приложения>
При изменении модели нужно выполнить те же действия, только скрипты для миграции создаются с параметром —auto вместо —initial
То есть когда вы изменили вашу модель, выполните:
python manage.py schemamigration <имя_приложения> --auto python manage.py migrate <имя_приложения>
Установка Django South
Для установки вам нужно выполнить
pip install south
и добавить south в INSTALLED_APPS settings.py вашего Django приложения.
После этого нужно выполнить
python manage.py syncdb
Это добавит необходимые south таблицы в базу данных, которые она использует для отслеживания выполненных изменений.
Внесение изменений в модель без удаления базы данных
Если в вашей базе данных уже есть информация, то перед изменением модели нужно сообщить south начальную структуру базы.
Допустим, мы хотим изменить модель Page в приложении pages, и при этом не хотим вносить уже записанные в базу данные заново.
Для этого выполните следующие команды:
python manage.py schemamigration pages --initial python manage.py migrate pages --fake
Первая команда создаст в каталоге приложения директорию migrations, в котором будет создан файл 0001_initial.py, описывающий создание текущей структуры.
При выполнении команды migrate, south применяет к базе все миграции, начиная с последней выполненной. Но в данном случае в базе уже есть нужные таблицы, поэтому первая миграция не сможет выполнится без ошибок.
Поэтому вторая команда запускается с ключом —fake — это даст south знать, что миграцию нужно отметить как выполненную, на самом деле не меняя базы.
Теперь внесите в модель нужные изменения. Допустим, мы добавили с помощью modeltranslation переводы полей title, seo_description и content на русский и украинский языки. При этом в базе должны быть созданы поля для хранения информации на указанных языках.
После этого выполните команду:
python manage.py schemamigration pages --auto add_pages_translation + Added field title_ru on pages.Page + Added field title_uk on pages.Page + Added field seo_description_ru on pages.Page + Added field seo_description_uk on pages.Page + Added field content_ru on pages.Page + Added field content_uk on pages.Page Created 0002_add_pages_translation.py. You can now apply this migration with: ./manage.py migrate pages
В команде schemamigration изменилось два параметра: вместо —initial мы указали —auto — это означает, что south попытается автоматически определить, что изменилось с момента последней миграции, и создать вторую миграцию, которая будет добавлять нужные поля в базу. Также я указал название для миграции: add_pages_translation.
После выполнения команды south сгенерировала файл 0002_add_pages_translation.py. Теперь нужно выполнить этот файл, внеся изменения в базу данных:
manage.py migrate pages Running migrations for pages: - Migrating forwards to 0002_add_pages_translation. > pages:0002_add_pages_translation - Loading initial data for pages.