On Fri, Nov 13, 2009 at 8:06 PM, Russell Keith-Magee
<freakboy3...@gmail.com> wrote:
>> The dynamic population of settings.DATABASES can happen at login time.
>>  I can use a statically configured alias as a template, just replacing
>> the username and password.  This new alias can be stored with a name
>> like '<username>@<template_alias_name>' and set in the session for use
>> as the default db alias in subsequent requests.
>>
>> The new multi-credential middleware would just have to take care of
>> getting the using() value from the session and putting it somewhere
>> for the ORM to use (perhaps a thread-local?).
>>
>> Is there an existing thread-local instance that would be appropriate
>> for storing this value?
>
> I'm not sure this will work as you expect. Django can be served in
> multi-process environments, and on multiple-server environments. As a
> result, there is no such thing as an in-process or in-thread store
> that is shared between all serving instances of a Django application.

Point taken.  Although it can be expected that session information is
shared across processes, changes made in the settings module of one
process will not be reflected in the other.  So, in order to
accomplish my goal, I will need to store the credentials in session.
The middleware will need to ensure that the database config contains
the alias, and create it if it doesn't.  Once that is done, it can
store the session-based default db alias in a thread local somewhere
for the ORM to use for the duration of the request-response cycle.

> If you want to share data between requests, you need to use a resource
> that is persistent across requests that might be served on completely
> different machines - like a cookie, or the database itself.
>

Understood.  Sessions are driven by cookies.

> As a mental model, you need to assume that each individual request
> will be served by a system process that will be created for that
> request, and destroyed as soon as the request is completed. Of course,
> this isn't how Django apps will be served in practice, but it
> accurately reflects the constraints that you need to adhere to in the
> general case.
>

Thats how I was picturing it, except when I was thinking about
dynamically manipulating settings.DATABASES.  Thanks for pointing out
the flaw in my reasoning.

>>
>> Would it make sense to factor out the connection selection logic into
>> a utility function with parameters that make it usable in all
>> contexts, thus yielding a single place to inject the check for the
>> request-specific default db alias (and perhaps other logic to support
>> master/slave, etc.)?
>
> That's the eventual intent - a callback or plugin that will be
> registered, probably with a model manager, that will provide an answer
> to the "which database should I be using for this query" question.
> Different implementations of this API will then exist for
> master/slave, sharding, etc. The exact form of this API is yet to be
> determined.
>

Is developing this API in scope for 1.2?

> I mentioned ConnectionHandler because you were talking about creating
> new database connections at runtime based on the user's credentials,
> and at some level, this will still need to happen. Tweaking
> ConnectionHandler is the alternative to trying to dynamically rewrite
> settings.DATABASE, not a solution to the 'find which connection to
> use' problem.
>

Ok.  I think I understand now.  I was leaning on the current
implementation of ConnectionHandler to do the right thing if I
dynamically manipulated settings.DATABASES.  Although it appears that
it would work, I now see that depending on it would be a bad idea.

Perhaps a better solution would be for ConnectionHandler to directly
support the concept of dynamic database configuration.  I suppose
there could be a structure similar to settings.DATABASES that lived on
a thread-local instance and potentially manipulated by middleware at
the beginning of each request.  ConnectionHandler.__getitem__ could
look in that structure for database config if the requested alias did
not exist in self.databases.
The "which database should I be using for this query" logic could
still be in control of which connection is requested, using a separate
mechanism to be aware of request-specific default db alias.

My impression is that my use case is not very common.  Therefore, it
may not make sense for it to be officially supported by django.

I'm going to run with some of these ideas in my custom version of
django and see what I come up with.

Thanks for your help.

-- 
Warren Smith

--

You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=.


Reply via email to