根据django中的请求动态设置数据库

时间:2014-12-10 13:05:17

标签: python django multi-tenant django-database

我正在用python-django编写一个多租户应用程序。

我想根据每个请求设置数据库连接。我想我可以写一个中间件,我们设置数据库用于该特定数据库。

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

但这不起作用。我该怎么办呢。方法错了或解决方案是否可行,最后怎么样?

2 个答案:

答案 0 :(得分:15)

这就是答案,希望它能在将来帮助某人:

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()

由于

答案 1 :(得分:1)

也许你可以使用:

https://docs.djangoproject.com/en/dev/topics/db/multi-db/#manually-selecting-a-database-for-a-queryset

Entity.objects.using('context1').all()
Entity.objects.using('context2').all()

根据请求选择/使用数据库。您可以在配置中定义多个DB:

DATABASES = {
    'context1': {
        'NAME': 'context1',
        'ENGINE': 'db.engine.to.use',
        'USER': 'xxx',
        'PASSWORD': 'xxx'
    },
    'context2': {
        'NAME': 'context2',
        'ENGINE': 'db.engine.to.use',
        'USER': 'xxx',
        'PASSWORD': 'xxx'
    }
}