Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dynamically set database based on request in django

I am writing a multi-tenant application with python-django.

I want to set database connection based on each request.I thought i could write a middleware where we set the database to be used for that particular database.

import re
from django.db import connections

class SetTenantDatabase(object):
    def process_request(self, request):
        pattern = re.compile("\\b(http://|https://|www.|.com|8000|:|//)\\W\\d+", re.I)
        words = request.get_host()        
        db_name = [pattern.sub("", words)][0].split('.')[0]
        connections.databases['new-alias'] = { 
        'default': {
                    'ENGINE': 'django.db.backends.postgresql_psycopg2',
                    'NAME': 'store1',
                    'USER': 'xxx',
                    'PASSWORD': 'xxx',
                    'HOST': '127.0.0.1',
    } 
                                              }
        conn = connections['new-alias']
        return None

but this is not working.How should i do this.Is the approach wrong or is the solution feasible, and lastly How?

like image 592
Vijay Shanker Avatar asked Dec 10 '14 13:12

Vijay Shanker


1 Answers

this is the answer, hope it helps someone in future:

import re
import threading 
request_cfg = threading.local()


class RouterMiddleware(object):
    def process_request( self, request):
        pattern = re.compile("\\b(http://|https://|www.|.com|8000|:|//)\\W\\d+", re.I)
        words = request.get_host()        
        db_name = [pattern.sub("", words)][0].split('.')[0]
        request_cfg.cfg = db_name
        return None

    def process_response( self, request, response ):
        if hasattr( request_cfg, 'cfg' ):
            del request_cfg.cfg
        return response


class DatabaseRouter (object):
    def _default_db( self ):
        if hasattr( request_cfg, 'cfg' ):
            return request_cfg.cfg
        else:
            return 'default'

    def db_for_read( self, model, **hints ):
        return self._default_db()

    def db_for_write( self, model, **hints ):
        return self._default_db()

Thanks

like image 142
Vijay Shanker Avatar answered Oct 25 '22 09:10

Vijay Shanker