Порядок исполнения миграций в Django - PullRequest
0 голосов
/ 18 апреля 2020

Я пытаюсь понять, как Django подходит к миграции, когда применяет их к базе данных.

В частности, предположим, что я смотрю на это приложение:

https://github.com/divio/aldryn-people/tree/master/aldryn_people/migrations

Я вставил точку останова в каждый файл миграции, как показано ниже:

def break_function(apps, schema_editor):
    print("Entered break_function() 0007")
    breakpoint()
    ...
 migrations.RunPython(break_function),   

При выполнении тестов я получаю следующее (Django пытается создать бренд новая база данных для тестирования и применяет все миграции для этого)

Creating test database for alias 'extra'...
Entered break_function() 0001
--Return--
> /home/user/sites/aldryn-people/aldryn_people/migrations/0001_initial.py(14)break_function()->No
ne                                                                                                    
-> breakpoint()
(Pdb) c
Entered break_function() 0002
--Return--
> /home/user/sites/aldryn-people/aldryn_people/migrations/0002_auto_20150128_1411.py(8)break_func
tion()->None                                                                                          
-> breakpoint()
(Pdb) c
Entered break_function() 0003
--Return--
> /home/user/sites/aldryn-people/aldryn_people/migrations/0003_auto_20150425_2103.py(9)break_func
tion()->None                                                                                          
-> breakpoint()
(Pdb) c
Entered break_function() 0004
--Return--
> /home/user/sites/aldryn-people/aldryn_people/migrations/0004_auto_20150622_1606.py(8)break_func
tion()->None                                                                                          
-> breakpoint()
(Pdb) c
Entered break_function() 0005
--Return--
> /home/user/sites/aldryn-people/aldryn_people/migrations/0005_auto_20150723_1508.py(10)break_fun
ction()->None                                                                                         
-> breakpoint()
(Pdb) c
Entered break_function() 0006
--Return--
> /home/user/sites/aldryn-people/aldryn_people/migrations/0006_person_groups.py(9)break_function(
)->None                                                                                               
-> breakpoint()
(Pdb) c
Entered break_function() 0007
--Return--
> /home/user/sites/aldryn-people/aldryn_people/migrations/0007_copy_group.py(8)break_function()->
None                                                                                                  
-> breakpoint()
(Pdb) c

Что меня интересует, так это порядок выполнения. Почему этот заказ, а не какой-то другой?

Я вижу логи c из 0001_initial, которые являются первыми (в зависимости от названия). После этого это просто в порядке, указанном в именовании файлов?

Может ли перечисление определенной миграции в dependencies заставить Django предварительно выполнить ее перед текущей?

Или раздел dependencies является просто декларативным и направлен на предотвращение несовместимых состояний БД?

Кроме того, существует ли определенный порядок c или способ, которым Django уничтожает существующий база данных, когда он запускает тесты? Применяется ли миграция в обратном (или каком-либо другом) порядке?

Ответы [ 2 ]

1 голос
/ 18 апреля 2020

Я часто задавался вопросом об этом сам, так что спасибо за размещение этого вопроса, так как он заставил меня на самом деле просмотреть документацию Django!

Основываясь на документации, числа в файлах просто там для справки разработчика. Django использует раздел зависимостей в каждом файле миграции, чтобы определить, когда на самом деле запустить миграцию. Таким образом, в основном, когда вы выполняете команду migrate, Django соберет все файлы миграции в вашем проекте и, используя зависимости в каждом файле миграции, выполнит изменения базы данных в правильной последовательности.

Полная документация ниже для вашего удовольствия от чтения: https://docs.djangoproject.com/en/3.0/topics/migrations/#workflow

1 голос
/ 18 апреля 2020

Первоначальная миграция имеет начальный = True, и он применяется первым.

Первоначальные миграции помечаются атрибутом initial = True класса в классе миграции. Если начальный атрибут класса не найден, миграция будет считаться «начальной», если это первая миграция в приложении (т. Е. Если она не зависит от какой-либо другой миграции в том же приложении).

все другие миграции зависят как минимум от одной миграции, которую следует применить до

Если существует внешний ключ для другого приложения, Django также будет включать в себя следующую миграцию текущего состояния приложения в зависимости также

Как документация Django относительно миграций * Зависимости 1012 *

, список миграций, от которых зависит эта.

Выполнение тестов воссоздает базу данных (нет необходимости понижать базу данных, она просто удаляется и воссоздается)

...