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=.
