ShEepCr3eper
ShEepCr3eper

Reputation: 151

Django migrations wrongly applying

Basic problem

I'm working on a django project where I'm using multiple databases with a custom router. Therefore, django should know which database to use for which app.

Now I came across some in my opinion weird behaviour and wanted to ask if anyone knew if that is the correct behaviour or not, especially because the github page doesn't seem to have an issues tracker.

To make the point clear, I'm using an extreme example, which I nonetheless tried. For testing purposes, I set the allow_migrate function to just return False.
I did create a custom router which overrides the allow_migrate function and I also registered it under the DATABASE_ROUTERS settings. The allow_migrate function is also called, as I checked it with some print statements.

How I understand the router usage

The way I understand the documentation for using multiple databases with a custom router, the allow_migration method specifies if a migration is to be applied for the current db, app_label and model_name. If it returns True, the migration is applied, if False, it is 'silently skipped' and therefore not applied.

What I expected

As I set the allow_migrate function to return False all the time, I expected that none of the yet unapplied migrations are applied.

What actually happens

The migrations are, as the documentation states, indeed 'silently skipped', but the table django_migrations is nonetheless being filled with the not yet applied migrations.

Why that is a problem

Therefore, if I had an actual logic in the allow_migrate function, even if the migration is correctly not applied, e.g. because the database is being tested for a specific app that should not be stored in that database, the django_migrations table of that database is being filled with wrong data.

So, is that the wanted behaviour? Am I just using the function allow_migrate wrong and should actually be using something else?

In case it is relevant, I'm using django version 3.1.2 and my database is a mariadb database.

Upvotes: 1

Views: 500

Answers (1)

ShEepCr3eper
ShEepCr3eper

Reputation: 151

I kind of figured out how the described problem is actually wanted.

It seems like for every database that django knows of, it is writing the migrations that one created with makemigrations into the django_migrations table, even if it did not actually apply the migration. Therefore, it keeps track of which migrations are newly created each time and only considers the migrations that are not stored in the django_migrations table.

To make it clear once again: In every case, if a migration is applied or not, it is written into the django_migrations table. If the migration is actually applied is only decided by the allow_migrate function I mentioned. There is no clue, however, if the migration actually got applied or not, except for looking into the tables that were changed in that database.

I suggest, that django should either say so in the console or just add a field applied into the django_migrations. Maybe I'm gonna prepare a pull request for that.

Upvotes: 2

Related Questions