Multiple Django Databases - Map Model to Database in Same Application
Question: I have searched all over for a solution for this but have been unable to find
anything.

I have one Django project, one application, two models and two database. I
would like one model to speak and sync exclusively to one database. This is
what I've tried:

**Settings**

    
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
            'NAME': 'database_a',                      # Or path to database file if using sqlite3.
            # The following settings are not used with sqlite3:
            'USER': 'user',
            'PASSWORD': 'xxxxxx',
            'HOST': 'localhost',                      # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
            'PORT': '',                      # Set to empty string for default.
        },
        'applicationb_db': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'database_b',
            'USER': 'user',
            'PASSWORD': 'xxxxxx',
            'HOST': 'localhost',
            'PORT': '',                 
        },
    }
    DATABASE_ROUTERS = ['fanmode4.router.ApiRouter']
    

**Models**

    
    
    from django.db import models
    
    class TestModelA(models.Model):
        testid = models.CharField(max_length=200)
        class Meta:
            db_table = 'test_model_a'
    
    class TestModelB(models.Model):
        testid = models.CharField(max_length=200)
        class Meta:
            db_table = 'test_model_b'
            app_label = 'application_b'
    

**Router**

    
    
    class ApiRouter(object):
        def db_for_read(self, model, **hints):
            if model._meta.app_label == 'application_b':
                return 'applicationb_db'
            return None
    
        def db_for_write(self, model, **hints):
            if model._meta.app_label == 'application_b':
                return 'applicationb_db'
            return None
    
        def allow_relation(self, obj1, obj2, **hints):
            if obj1._meta.app_label == 'application_b' or \
               obj2._meta.app_label == 'application_b':
               return True
            return None
    
        def allow_syncdb(self, db, model):
            if db == 'applicationb_db':
                return model._meta.app_label == 'application_b'
            elif model._meta.app_label == 'application_b':
                return False
            return None
    

the application name is "api". Basically with this setup, if I sync the
database it will only sync on the default db. If I sync the database
specifying the second database `python manage.py syncdb
--database=applicationb_db`, it will not sync anything to the second database.

I am simply trying to achieve the following:

  * Everything for TestModelA goes to default database
  * Everything for TestModelB goes to applicationb_db database
  * Everything else goes to the default database


Answer: Instead of using `model._meta.app_label` you can use `model` to check which
model it is and return appropriate DB.

You can update the router as:

    
    
    class ApiRouter(object):
        def db_for_read(self, model, **hints):
            if model == TestModelB:
                return 'applicationb_db'
            return None
    
        def db_for_write(self, model, **hints):
            if model == TestModelB:
                return 'applicationb_db'
            return None
    
        def allow_relation(self, obj1, obj2, **hints):
            if model == TestModelB:
               return True
            return None
    
        def allow_syncdb(self, db, model):
            if model == TestModelB:
                return True
            else:
                return False
            return None
    

