Master and Read Replica Database setup in Django

Rahul Kumar
2 min readJun 26, 2021

Master and Read Replica architecture is used to distribute the load of the database to avoid overhead, where all the write operation goes to the master DB and all the read goes to the replica DB.

Step 1: In the settings.py file define the database connection string and two more variable USE_REPLICA_DATABASE, DATABASE_ROUTERS

USE_REPLICA_DATABASE
This variable will be used in the router to determine whether to use replica DB or not, while running the test case we can set it False to avoid conflict.

DATABASE_ROUTERS
It contains a list of routers that will be used to determine which database to use when performing a database query.

DATABASES = {
"default": {
"ENGINE": 'django.db.backends.postgresql_psycopg2',
"NAME": env.str('MASTER_DB_NAME'),
"USER": env.str('MASTER_DB_USER'),
"PASSWORD": env.str('MASTER_DB_PASS'),
"HOST": env.str('MASTER_DB_HOST'),
"PORT": env.str('MASTER_DB_PORT')
},
'replica': {
"ENGINE": 'django.db.backends.postgresql_psycopg2',
"NAME": env.str('REPLICA_DB_NAME'),
"USER": env.str('REPLICA_DB_USER'),
"PASSWORD": env.str('REPLICA_DB_PASS'),
"HOST": env.str('REPLICA_DB_HOST'),
"PORT": env.str('REPLICA_DB_PORT')
}
}
USE_REPLICA_DATABASE = env.bool('USE_REPLICA_DATABASE', default=False)DATABASE_ROUTERS=[router.ReplicaRouter]

Step 2: Create a router.py file here goes the code which will route all the write operations to the master DB and read to the replica DB.

from your_project.settings import USE_REPLICA_DATABASEclass ReplicaRouter:    def db_for_read(self, model, **hints):
"""
Reads go to the replica.
"""
if USE_REPLICA_DATABASE:
return 'replica'
return None
def db_for_write(self, model, **hints):
"""
Writes always go to primary.
"""
return 'default'
def allow_relation(self, obj1, obj2, **hints):
"""
Relations between objects are allowed if both objects are
in the primary/replica pool.
"""
db_set = {'default', 'replica'}
if obj1._state.db in db_set and obj2._state.db in db_set:
return True
return None
def allow_migrate(self, db, app_label, model_name=None,**hints):
return True

Step 3: Create a .env file and assigned values to the variables to keep things flexible also best practice is that all the variables which likely to change in the near future read from the .env file.

MASTER_DB_NAME=db_name 
MASTER_DB_USER=db_user_name
MASTER_DB_PASS=db_password
MASTER_DB_HOST=127.0.0.1
MASTER_DB_PORT=5432
REPLICA_DB_NAME=replica_db_name
REPLICA_DB_USER=replica_db_user_name
REPLICA_DB_PASS=replica_db_pass
REPLICA_DB_HOST=127.0.0.1
REPLICA_DB_PORT=5432
USE_REPLICA_DATABASE=True

For more detailed information visit https://docs.djangoproject.com/en/3.1/topics/db/multi-db/
Happy Learning!!!

--

--