Friday, February 6, 2015

Dynamically changing database routing for Django database accesss

Django's db routing allows to define read and write databases, however sometimes that is not enough

Why just read and write are not good enough
-- Multi op function rely on both sources being the same and reflecting updates
-- However with transaction isolation that is not possible
-- Need to set a context based db as opposed to a simple per read/per write, that is some other source of data that is not read or write database

This helps
http://python.dzone.com/articles/django-switching-databases

Recently a project I have completed a while ago needed a small modification, the modification was such that each app server would have a Read Only replica of the master database, and while we would be unable to manipulate the data in case we lost connectivity to the Read/Write Master, we could at least continue to serve data that is already contained in the database.

Luckily the project was in Django and one of the things that Django provides is ability to use multiple databases.  Django also provides a concept of a database router that allows to direct reads and write to different databases.  That should be enough right?  Wrong.  Imagine a function that first reads an objects from a database, modifies it and writes it back, Django does not like that because the read database from where the object came form is different from the write databse.  So what needs to be does it to permit relations between the objects and databases or since the tables are identical and hence the objects contained as well just permit relations between between objects:
allow_relation(obj1, obj2, **hints)