Changes between Initial Version and Version 2 of Ticket #28939


Ignore:
Timestamp:
Dec 19, 2017, 4:54:39 AM (7 years ago)
Author:
Nick Pope
Comment:

Hi Simon,

Sorry - false alarm.

I did some digging and found tests.prefetch_related.tests.MultiDbTests which seems to show my scenario working correctly.

I've subsequently realised that I wasn't handling instance._state.db correctly in db_for_read() in my router.

It may be worth improving the documentation on database routers and/or prefetch_related() warning of this pitfall.

I have left this ticket open, but feel free to close it if you don't think the documentation needs improving.

Here is (an example of) my fixed database router:

class Router(object):

    def __init__(self):
        self.mapping = {'special': 'other'}

    def db_for_read(self, model, **hints):
        db = self.mapping.get(model._meta.app_label, 'default')
        instance = hints.get('instance')
        return instance._state.db or db if instance else db

    def db_for_write(self, model, **hints):
        return self.mapping.get(model._meta.app_label, 'default')

    def allow_relation(self, obj1, obj2, **hints):
        db1 = self.mapping.get(obj1._meta.app_label, 'default')
        db2 = self.mapping.get(obj2._meta.app_label, 'default')
        return db1 == db2

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        return db == self.mapping.get(app_label, 'default')

Beforehand, db_for_read() was the same as db_for_write().

Essentially there are two databases (default and other) which also both have read-only connections to a replica (default-ro and other-ro). This is an application-routing router - everything goes to default unless it is from the special application which goes to other. Typically we opt-in to using the read-only connections via QuerySet.using() and this is where things then broke due to not handling instance._state.db.

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #28939

    • Property Triage Stage UnreviewedAccepted
    • Property Component Database layer (models, ORM)Documentation
    • Property Type BugCleanup/optimization
  • Ticket #28939 – Description

    initial v2  
     1**Update:** I should have mentioned that I was using a custom database router. I now know this issue occurred due to a bug in that router.
     2
     3----
     4
    15I've run into an case with prefetching where the connection used for the prefetch queries is not the one I would expect:
    26
Back to Top