Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - Runtime database switching

In my work we want to run a server with multiple databases. The databases switching should occur when you acces a url like http://myapp.webpage.com or http://other.webpage.com. We want to run only one server instance and at the moment of the HTTP request switch the database and return the corresponding response.

We've been looking for a mantainable and 'Django-friendly' solution. In our investigation we have found possible ways to do this, but we have not enough information about.

Option 1: Django middleware

The django middleware runs each time the server receive a HTTP request.

  1. Making a database switch here could be the best option but using django database routers as far as I know only allow to change the database for a model or group or models.

  2. Another option is to set a django model manager instance in the middleware and force all models to re-assign the objects attribute from an added attribute in the custom middleware.

  3. My last option is to create a new attribute in the request object received by the middleware that return the database alias from settings.py and in each model query use the using method.

Option 2: Class-based View Mixin

Create a mixin that use the past three options, but I the mixin must be set in ALL the Class-based views. If a programmer forget to set the mixin and it comes to a production server, the data could be (or stop being) in the right database, and I don't wanna take the risk.

Option 3: Changing the database settings in runtime

This option works but Is not recommended and is too risky.

UPDATE:

How this works?

middlewares.py

import django.conf as conf
import os.path


class SelectDB(object):

    def process_request(self, request):
        print request.META['HTTP_REFERER']
        file_database = open("booklog/database.txt", "r")
        database = file_database.read(10)
        file_database.close()
        if database != 'default':
            conf.settings.DATABASES['default']['NAME'] = database

Any information that help us to solve will be greatly appreciated.

like image 692
MikeVelazco Avatar asked May 13 '15 23:05

MikeVelazco


1 Answers

Answer (it worked for me)

The question was already answered here, in stackoverflow. I'd love this functionality were in django. It was a bit hard to find the way to make this possible.

I think that is important to comment the great work that Wilduck made with the django plugin django-dynamic-db-router, it's a great plugin that makes possible this operation in (a bit) different way.

Thanks a lot to @JL Peyret and @ire_and_curses.

And as an answer to @ire_and_curses. At least in this moment, in the project I'm working it's what we need. In previous projects we needed a similar behavior and made one server per instance was terrible to mantain and update each server, even automating the process.

like image 200
MikeVelazco Avatar answered Nov 14 '22 04:11

MikeVelazco