Фёдор Борщёв

Как переименовать приложение в Django

Как-то на бекенде для инфобизнеса меня перестало устраивать название приложения в Django. Всё просто — когда я начинал проект, я продавал только курсы, и приложение с моделями курсов называлось courses. Потом появились записи этих курсов (record) и наборы (bundles). Конечно мне захотелось переименовать приложение courses в products, чтобы уменьшить когнитивную нагрузку при чтении кода.

К сожалению, я не нашёл ни одного решения, кроме стрёмного django-rename-app, который предлагал мне выполнять management-команды в консольке на проде. Кроме того, что это ломает любые пайплайны CI\CD, там ещё и код был не очень понятный. Так что в итоге я решил сделать это сам. Оказалось сложно, поэтому я написал эту инструкцию.

Исходные условия:

  • БД — SQLite. На PostgreSQL наверное тоже будет работать, но я не проверял.
  • CI\CD пайплайн, который запускает миграции при каждом деплое.
  • Данные терять нельзя.
  • Мы не стесняемся править старые миграции.

Все изменения я делал на живом проекте, так что примеры будем брать прямо из пулл-реквестов.

  • Подменяем имя приложения в истории миграций: ./manage.py makemigrations <some-other-app> -n RenameOldApp --empty. Коммит.
  • Деплоим миграцию на прод. После этого шага ничего нельзя деплоить до конца.
  • Делаем новый пулл-реквест.
  • Переименовываем папку с приложением: git mv courses products
  • Заменяем все упоминания старого приложения в миграциях. Коммит.
  • У всех моделей в новом приложения в Meta прописываем db_table с именем старого приложения. В моём случае, если модель называется bundle и лежала в приложении courses, нужно прописать db_table = 'courses_bundle'. Коммит.
  • В старых миграциях, которые используют операцию CreateTable, добавляем новую db_table в options. Коммит.
  • Меняем упоминания приложения в коде, можно автозаменой. Мой коммит, если важно.
  • Проверяем, ./manage.py makemigrations --check. Новых автоматических миграцией был не должно, ошибок тоже.
  • Деплоим на прод.

В итоге у нас получается два деплоя. Первый подменяет миграции, а второй — код. В результате модели будут лежать по новому адресу, но ходить в старые таблицы. Для меня это было плюсом, т.к. не пришлось переделывать аналитические SQL-запросы, которые ходят в базу из Metabase.