10

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.

MikeVelazco
  • 885
  • 2
  • 13
  • 30
  • Isn't this the whole reason database routers exist? What disadvantage do you perceive to that solution? – ire_and_curses May 13 '15 at 23:16
  • Please correct me if im wrong but, as I far I remember the database routers only work for some models that you define, not the whole database – MikeVelazco May 13 '15 at 23:21
  • hmmm, perhaps a dumb question, but how robust will this be to user #1 being in myapp's db and user #2 simultaneously being in other's db? that would kinda preclude option #3 regardless of risk or not, no? – JL Peyret May 13 '15 at 23:24
  • No, it works on the whole DB. I use this to fall back to a backup database if access to the primary becomes slow. It works transparently. – ire_and_curses May 13 '15 at 23:24
  • @ire_and_curses I know this is dumb, but, could you teach me a chunk of code? If I generate the model router how can I catch the request object in order to obtain the url? Can I know when a model router is run? Thanks a lot – MikeVelazco May 13 '15 at 23:31

1 Answers1

4

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.

Community
  • 1
  • 1
MikeVelazco
  • 885
  • 2
  • 13
  • 30