Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Multi-db: is database routing per request possible?
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  6 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
johan de taeye  
View profile  
 More options Jun 15 2010, 7:12 am
From: johan de taeye <johan.de.ta...@gmail.com>
Date: Tue, 15 Jun 2010 04:12:53 -0700 (PDT)
Local: Tues, Jun 15 2010 7:12 am
Subject: Multi-db: is database routing per request possible?
Hello,

In my application a number of databases are configured with identical
schemas.
From a dropdown box on the screen, the user selects the database he/
she wants to work with.  The selected database is stored on the
cookie.
An object with the same primary key can be created in each schema by
the user.

The above means objects can't be routed to the correct database based
on their primary key.
Only by looking at the request I know what database is required.

From the documentation (and after digging a bit in the code) I think
the database router concept doesn't support this type of usage.
Is this possible somehow?
Is it feasible to pass the request as a hint to the router somehow?

All feedback appreciated...

Johan


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Alexander Jeliuc  
View profile  
 More options Jun 15 2010, 8:15 am
From: Alexander Jeliuc <jeliucalexa...@gmail.com>
Date: Tue, 15 Jun 2010 15:15:31 +0300
Local: Tues, Jun 15 2010 8:15 am
Subject: Re: Multi-db: is database routing per request possible?

I didn't work with multidb but I think it is possible anyway... try it using
additional middleware... for example.. change dynamically db settings...
etc

On Tue, Jun 15, 2010 at 2:12 PM, johan de taeye <johan.de.ta...@gmail.com>wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Russell Keith-Magee  
View profile  
 More options Jun 15 2010, 8:17 am
From: Russell Keith-Magee <russ...@keith-magee.com>
Date: Tue, 15 Jun 2010 20:17:55 +0800
Local: Tues, Jun 15 2010 8:17 am
Subject: Re: Multi-db: is database routing per request possible?
On Tue, Jun 15, 2010 at 7:12 PM, johan de taeye

You can't do this with a router; as you've noted, the router doesn't
have any information about the request in which it is being used.

However, you could do it by manually requesting your database
connection whenever you use the database. For example:

Author.objects.using('otherdb').filter(...)

will perform a query that is guaranteed to operate on the 'otherdb',
regardless of what the router says.

The parameter 'otherdb' is just a string, so it could be determined
using some logic based on the request. This will require that you pass
the database assignment information around your project -- but you
would have needed to do this anyway if you wanted to pass hints to the
router.

Yours,
Russ Magee %-)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
johan de taeye  
View profile  
 More options Jun 15 2010, 9:11 am
From: johan de taeye <johan.de.ta...@gmail.com>
Date: Tue, 15 Jun 2010 06:11:47 -0700 (PDT)
Local: Tues, Jun 15 2010 9:11 am
Subject: Re: Multi-db: is database routing per request possible?

> You can't do this with a router; as you've noted, the router doesn't
> have any information about the request in which it is being used.

> However, you could do it by manually requesting your database
> connection whenever you use the database. For example:

> Author.objects.using('otherdb').filter(...)

> will perform a query that is guaranteed to operate on the 'otherdb',
> regardless of what the router says.

I was able to get this part working fine.  Since most views are based
on a reuable generic one this was pretty easy to do anyway.

Getting ModelForms (or ModelAdmin) to work with foreign keys is a
different story:  When the form/model is validated, the field value is
searched in the source table to verify the key exists. This lookup
uses the _default_manager (see code below), which isn't aware of the
request any more and always checks on the default database (unless I
can route it).  As a result I always get a validation error on the
form.

Looks like I need a patched/smarter RelatedField that is aware of the
database to look in?

Regards,

Johan

Snippet from django/db/models/fields/related.py:
class ForeignKey(RelatedField, Field):
...
    def validate(self, value, model_instance):
        if self.rel.parent_link:
            return
        super(ForeignKey, self).validate(value, model_instance)
        if value is None:
            return

        qs =
self.rel.to._default_manager.filter(**{self.rel.field_name:value})
####   ALWAYS CHECKS IN DEFAULT DATABASE
        qs = qs.complex_filter(self.rel.limit_choices_to)
        if not qs.exists():
            raise
exceptions.ValidationError(self.error_messages['invalid'] % {
                'model': self.rel.to._meta.verbose_name, 'pk': value})


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Russell Keith-Magee  
View profile  
 More options Jun 15 2010, 8:25 pm
From: Russell Keith-Magee <russ...@keith-magee.com>
Date: Wed, 16 Jun 2010 08:25:15 +0800
Local: Tues, Jun 15 2010 8:25 pm
Subject: Re: Multi-db: is database routing per request possible?
On Tue, Jun 15, 2010 at 9:11 PM, johan de taeye

You're in somewhat uncharted territory here, so I can't give you a
simple prepared answer. However, you certainly appear to be on the
right track.

It's also possible that you've discovered an edge case bug -- looking
at the code, my gut tells me that the _default_manager call should be
forced onto the same database as model_instance - i.e., the query
should be:

    db = router.db_for_read(self.rel.to, instance=model_instance)
    qs = self.re.to._default_manager.using(db).filter(**self.rel.field_name:value})

or similar. I'd need to do more tests to confirm this, though. Feel
free to log a bug if you can reduce this to a test case that
demonstrates that this is indeed a bug.

Yours,
Russ Magee %-)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
johan de taeye  
View profile  
 More options Jun 16 2010, 3:01 am
From: johan de taeye <johan.de.ta...@gmail.com>
Date: Wed, 16 Jun 2010 00:01:01 -0700 (PDT)
Local: Wed, Jun 16 2010 3:01 am
Subject: Re: Multi-db: is database routing per request possible?
Russ,

Your gut feeling confirms my suspicion.

Changing the lines to the following fixes my problem:
        db = model_instance._state.db
        if db is None:
            db = router.db_for_write(model_instance.__class__,
instance=model_instance)
        qs =
self.rel.to._default_manager.using(db).filter(**{self.rel.field_name:value} )

The validation of many2many fields (further down in the same file) has
a similar issue and would need fixing too.

I'll file a bug on the topic.

I somehow feel a bit uncomfortable with this approach: the formfield
constructor accepts the "using" argument to direct the queries to a
database, but since the validation is model-based (not form-based)
that info is not used in validation. You rely on guess-work like the
above or on the fact that the routing logic is in sync with the
"using" argument you provided. This can't be DRY...

Regards,

Johan

On Jun 16, 2:25 am, Russell Keith-Magee <russ...@keith-magee.com>
wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »