On Thu, Nov 12, 2009 at 5:17 PM, Russell Keith-Magee
<[email protected]> wrote:
>> 1. Retrieve the credentials from the session.
>> 2. Create a new, or update an existing, entry for those credentials in
>> the database configuration.
>> 3. Somehow ensure that the using() operator is used on all ORM operations.
>
> This sounds a little more dynamic that I was anticipating.
>
> Multi-DB changes the way you define your database - instead of
> DATABASE_HOST, DATABASE_NAME etc, you have a single DATABASES
> dictionary, with each key-value pair representing a full database
> configuration, including signin credentials.

I've looked through the code in the SVN multdb branch and Alex's
GitHub and thought about this a little more.

I realize now that I don't need to store the credentials in session,
just the default db alias.

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?

> The process of actually
> opening a connection is handled by a ConnectionHandler class in
> django.db.utils.
>
> Although we haven't provided any way to override this, I suppose it
> could be replaced by an alternate implementation that creates
> connections based on credentials obtained from a session or something
> similar. I haven't given this much thought though.
>

Though django.db.utils.ConnectionHandler is the broker of all database
connections, I'm concerned that overriding connection selection here
would overrule explicit alias declaration such as Model.Meta.using,
Model.save(using=), etc.  Though it would work in my case (I'm not
using those features), it feels heavy-handed.  However, since the
multi-credential use case adds an extra dimension to an already
complex problem, perhaps it does make sense for it to be mutually
exclusive with the other multi-db enabled use cases.

What I originally envisioned was injecting the check of the request
specific default into the connection selection logic just ahead of
DEFAULT_DB_ALIAS.  Unfortunately, the connection selection logic
exists in several places in the code and is not all the same (for
reasons I haven't taken the time to fully understand).

To avoid changing any of the existing connection-selection code, I
suppose I could change DEFAULT_DB_ALIAS to a custom string subclass
that was smart enough to check for the request-specific value when
asked for his own value, but that seems like an overly complex and
counter-intuitive solution to a relatively simple logic problem.

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.)?

-- 
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 [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=.


Reply via email to