Home > other >  Django db_router does not exclude app models as expected
Django db_router does not exclude app models as expected

Time:05-20

I am trying to create an application where one server communicates with many other worker servers. Those servers will each have their own DB which should only contain the tables for their own models. I have created a database router which unfortunately does not work as the migrate command continues to create auth, contenttypes and virtually all Django application models in the database that as per the router, should contain none of that and only the worker server specific models.

Expected in database:

  • Worker Server Model 1

Actually produced in database:

  • Worker Server Model 1
  • auth_group
  • auth_group_permissions
  • auth_permission
  • auth_user
  • auth_user_groups
  • all the rest of the django models

Code in Settings:

    DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'server_1_db',
        'USER': 'postgres',
        'PASSWORD': 'admin',
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}

DATABASE_ROUTERS = ['ApplicationServer_2.db_routers.RestRouter']

Router code:

class RestRouter:

app_labels = {"DoNOTadd", "auth", "admin", "sessions", "contenttypes"}

def db_for_read(self, model, **hints):

    if model._meta.app_label not in self.app_labels:
        return 'default'
    return "For read db"

def db_for_write(self, model, **hints):

    if model._meta.app_label not in self.app_labels:
        return "default"
    return "For write db"

def allow_relation(self, obj1, obj2, **hints):

    if (
        obj1._meta.app_label not in self.app_labels or
        obj2._meta.app_label not in self.app_labels
    ):
       return True
    return None

def allow_migrate(self, db, app_label, model_name=None, **hints):
    if app_label not in self.app_labels:
        print(app_label)
        return db == "default"
    return None

What do I do wrong? In allow migrate, only the expected app_label is printed, meaning that auth, admin etc should not be migrated, yet they get migrated nonetheless?

CodePudding user response:

Your allow_migrate should return False to indicate that apps other than app_labels are not allowed to migrate in this database:

def allow_migrate(self, db, app_label, model_name=None, **hints):
    if app_label not in self.app_labels:
        return db == "default"
    return False

Returning None as you do means this router doesn't care about this migration. From the docs for allow_migrate:

Determine if the migration operation is allowed to run on the database with alias db. Return True if the operation should run, False if it shouldn’t run, or None if the router has no opinion.

  • Related