You'll be able to do this through Automatic Database Routing . It is a rather extensive configuration, but we will use a simple and practical example (removed from the documentation).
This will have some databases: one for app auth
and all other apps will use a primary / replica configuration with two replicas just for reading. This would be the configuration for the databases:
DATABASES = {
'default': {},
'auth_db': {
'NAME': 'auth_db',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'swordfish',
},
'primary': {
'NAME': 'primary',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'spam',
},
'replica1': {
'NAME': 'replica1',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'eggs',
},
'replica2': {
'NAME': 'replica2',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'bacon',
},
}
Now we're going to have to deal with routing. First let's create a router that will know how to send queries from the app auth
to auth_db
:
class AuthRouter:
"""
Um router para controlar todas as operações de banco de
dados dos models da app auth.
"""
def db_for_read(self, model, **hints):
"""
Definição do nome do banco para leitura.
"""
if model._meta.app_label == 'auth':
return 'auth_db'
return None
def db_for_write(self, model, **hints):
"""
Definição do nome do banco para escrita.
"""
if model._meta.app_label == 'auth':
return 'auth_db'
return None
def allow_relation(self, obj1, obj2, **hints):
"""
Permite relações se um model na app auth está envolvido.
"""
if obj1._meta.app_label == 'auth' or \
obj2._meta.app_label == 'auth':
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
"""
Certifica que a app auth aparece apenas no banco 'auth_db'.
database.
"""
if app_label == 'auth':
return db == 'auth_db'
return None
And here we are going to create a router that will send everything from the other apps to our primary / replica configuration, randomly choosing which replica it will read:
import random
class PrimaryReplicaRouter:
def db_for_read(self, model, **hints):
"""
Leitura vai para um dos dois, aleatoriamente.
"""
return random.choice(['replica1', 'replica2'])
def db_for_write(self, model, **hints):
"""
Escrita sempre no primary
"""
return 'primary'
def allow_relation(self, obj1, obj2, **hints):
"""
Relações entre objetos são permitidas se ambos objetos
estão no primary/replica.
"""
db_list = ('primary', 'replica1', 'replica2')
if obj1._state.db in db_list and obj2._state.db in db_list:
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
return True
At the end of it all, you will add DATABASE_ROUTERS
to your settings.py
project file, with the path to the two previously created classes.
DATABASE_ROUTERS = ['path.to.AuthRouter', 'path.to.PrimaryReplicaRouter']
You have this other post that also addresses the same subject.