Как переименовать приложение в 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.