Django migrations, как и сам django, это просто волшебный инструмент. Но при этом “волшебство” порой мешает сделать задачу как нужно. Одно из таких “волшебств”, связано с созданием индекса в PostgreSQL без блокировки на запись. Подробнее об этом есть в документацаии.
Стандартный migrations.AddIndex
, который создается автоматически при добавлении индекса в модель, выполняет обычный
CREATE INDEX ...
и если мы хотим выкатить быстренько в прод и не заблочить запись в таблицу, то нужно отделить
django models state и фактический заапрос в SQL. Для этого есть migrations.SeparateDatabaseAndState
.
Весь процесс я сделал в репозиторий ниже по шагам (каждый коммит отдельный шаг)
- В сгенерированном командой makemigrations файле находим
migrations.AddIndex
и переносим в параметрstate_oprations
конструктораmigrations.SeparateDatabaseAndState
ссылка на коммит - В параметре
database_oprations
конструктораmigrations.SeparateDatabaseAndState
добавляемmigrations.RunSQL()
внутри которого добавимsql
иreverse_sql
, соответственно запрос выполняемый при “накатке” и “откатке” миграацаии ссылка на коммит - Выключаем выполнение запросаа в транзакции ссылка на коммит
После этого можем запускать migrate
и получится что django будет понимать что индекс в бд и сама бд получит запрос с CONCURRENTLY. Т.е. мы слегка обманули “волшебство”.