multi database model not creating tables or applying migrations in non-default database?

I have a django app (Django==5.0.7) that uses the default sqlite database for Users/Groups and django core stuff, and also other databases configured in settings.py DATABASES. However what I see is that django creates the migrations for other app, but never applies them. I annotated the allow_migrate method with a print statement, and the problem seems that it it doesn’t even check the router whether it should migrate the second database for myapp2. I can force it to create the second set of tables with --run-syncdb but it seems like I am missing something simple.

example:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    },
    'myapp2': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'myapp2.sqlite3',
    }
}

There are 2 apps myapp and myapp2, the models from the first should be in the default database, and the models from the second in the “myapp2” database;

DATABASE_ROUTERS = ['project.database_router.TestRouter']

TestRouter:

class TestRouter:

    route_app_labels = {"myapp2"}

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return "myapp2"
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return "myapp2"
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if (
                obj1._meta.app_label in self.route_app_labels
                or obj2._meta.app_label in self.route_app_labels
        ):
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        print(f"checking allow_migrate db {db} app_label {app_label} model_name {model_name}")
        if app_label in self.route_app_labels:
            return db == "myapp2"
        return None

if I then run

python manage.py migrate
python manage.py makemigrations myapp2
python manage.py migrate myapp2

the myapp2 database is created, but no tables. Though it reported that it created the migrations and applied them successfully.

If I annotate the allow_migate method of the database router, like so:

the output suggests, that its not calling allow_migrate for these migrations;

(venv) [project] $ python manage.py migrate myapp2
checking allow migrate app_label myapp2 db default model_name managed1
checking allow migrate app_label myapp2 db default model_name managed1
checking allow migrate app_label myapp2 db default model_name managed1
checking allow migrate app_label myapp2 db default model_name managed1
checking allow migrate app_label myapp2 db default model_name managed1
checking allow migrate app_label myapp2 db default model_name managed1
checking allow migrate app_label myapp2 db default model_name unmanaged1
checking allow migrate app_label myapp2 db default model_name unmanaged1
checking allow migrate app_label myapp2 db default model_name unmanaged1
checking allow migrate app_label myapp2 db default model_name unmanaged1
checking allow migrate app_label myapp2 db default model_name unmanaged1
checking allow migrate app_label myapp2 db default model_name unmanaged1
Operations to perform:
  Apply all migrations: myapp2
Running migrations:
  Applying myapp2.0001_initial...checking allow migrate app_label myapp2 db default model_name managed1
 OK

Ah ok, so it seems that when applying migrate, you have to pass the --database myapp2 option

1 Like

If that is the solution mark you post as the solution :slight_smile: