MadPhysicist
MadPhysicist

Reputation: 5831

Order of Execution of Migrations in Django

I am trying to understand how Django approaches migrations when it applies them to the database.

In particular, suppose I am looking at this app:

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

I have inserted a breakpoint into each migration file, similar to this:

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

When running tests, I get the following (Django tries to build a brand new database for testing and applies all the migrations to do so)

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

What I am wondering about is the order of execution. Why this order and not some other?

I can see the logic of 0001_initial being the first (based on the name). After that, is it simply in the order specified in the naming of the files?

Does listing a certain migration in dependencies make Django pre-run it before the current one?

Or is the dependencies section simply declarative and aims to prevent inconsistent states of the DB?

Also, is there a specific order or way how Django destroys an existing database when it runs tests? Does it apply migrations in reverse (or some other) order?

Upvotes: 2

Views: 1958

Answers (2)

iklinac
iklinac

Reputation: 15738

Initial migration has initial=True and it is applied first.

Initial migrations are marked with an initial = True class attribute on the migration class. If an initial class attribute isn’t found, a migration will be considered “initial” if it is the first migration in the app (i.e. if it has no dependencies on any other migration in the same app).

all other migrations have dependency at-least on one migration that should be applied prior

If there is a foreign key to another app Django would also include following app current state migration in dependencies also

As Django documentation regarding migrations

dependencies, a list of migrations this one depends on.

Running tests recreates database (there is no need to downgrade database it just deletes it and recreates)

Upvotes: 1

brandonris1
brandonris1

Reputation: 455

I have often wondered about this myself so thank you for posting this question as it forced me to actually look through the Django documentation!

Based on the documentation, the numbers in the files are purely there for developer reference. Django uses the dependencies section in each migration file to determine when to actually run the migration. So basically, when you execute the migrate command, Django will gather up all the migration files in your project and, using the dependencies in each migration file, execute the database modifications in proper sequence.

The complete documentation is listed below for your reading pleasure: https://docs.djangoproject.com/en/3.0/topics/migrations/#workflow

Upvotes: 2

Related Questions