On 31/01/12 11:45, akaariai wrote:
> On Jan 31, 12:01 am, Tom Eastman <t...@catalyst.net.nz> wrote:
>> Hey guys,
>>
>> I'm writing a django project that will require me to route queries to
>> certain large databases based on who the logged in user is.
>>
>> So all the tables for django.contrib.auth and session and stuff will be
>> in the 'central' database, as well as a table that maps users to which
>> database they need to use for the main app.
>>
>> Can you help me come up with a way of routing database queries this way
>> using a Django database router?
>>
>> At the start of the view could I take the logged in user from
>> request.user or wherever it is, and some how provide that variable to my
>> database router for the rest of the request?
>>
>> All suggestions welcome.

> 
> I think the best solution forward is to use threading.local to store
> the request.user. So, something like this should work:
>   - have a middleware that stores the request.user in threading.local
>   - database routers just fetch the request.user from the
> threading.local storage.


Thanks Anssi!

Here is my solution, I wonder if you could just tell me if you think
there's a major problem with it.

In simplistic terms, the goal is "whenever a model from wxdatabase is
accessed, route the query to the database specified in the user's
organization's field".

It consists of a piece of django middleware and a db_router.

I guess my main question is: am I using threading.local() correctly?

Cheers!

        Tom


##################################
##################################
import threading

_local = threading.local()

class WXDatabaseMiddleware(object):
    def process_request(self, request):
        _local.wx_database_label = None

        try:
            profile = request.user.get_profile()
            _local.wx_database_label = profile.organization.database.label
        except:
            ## This exception needs to be logged!
            pass


class WxRouter(object):
    def _get_database_label(self):
        return _local.wx_database_label

    def read_and_write(self, model, **hints):
        if model._meta.app_label == "wxdatabase":
            return self._get_database_label()
        else:
            return None

    db_for_read  = read_and_write
    db_for_write = read_and_write

###################################
###################################

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to