Opened 3 years ago
Closed 3 years ago
#33501 closed Bug (fixed)
order_with_respect_to uses incorrect database alias
Reported by: | Damian Posener | Owned by: | Damian Posener |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.2 |
Severity: | Normal | Keywords: | |
Cc: | Simon Charette | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
PR: https://github.com/django/django/pull/15409
When calling set_RELATED_order on a model that uses order_with_respect_to, if a DB router exists that routes that model to a non-default database, the routing is ignored, causing a datbase error to occur.
I've tracked this down to the method_set_order function here:
https://github.com/django/django/blob/3.2.12/django/db/models/base.py#L2117
This function updates using=None
to using=DEFAULT_DB_ALIAS
, which then overrides any database routing set up on the model manager. It should just pass through using=None
so that the manager can deal with determining the correct connection to use.
I believe this got inadvertently broken in #30106 - previously the using
parameter was actually being ignored, but when that got fixed it caused this new error. :)
Change History (7)
comment:1 by , 3 years ago
Description: | modified (diff) |
---|
comment:2 by , 3 years ago
Cc: | added |
---|---|
Needs tests: | set |
Owner: | changed from | to
Status: | new → assigned |
Triage Stage: | Unreviewed → Accepted |
Type: | Uncategorized → Bug |
follow-up: 5 comment:3 by , 3 years ago
Interestingly this means that the code prior to 8d2dcc47cd7f6069a1fa2c5b67a329cec5846b7e was broken in another way. It use to open a transaction against the default database but the following chunked updates were performed against whatever db_for_write
returned afterwards making them non-atomic when performed against the non-default database.
This makes me realize that bulk_update
doesn't set self._for_write = True
before accessing self.db
(like all other create and update queryset methods do) which means the aforementioned issue is affects this function as well so I'll file another issue for it and assign it to myself.
You patch looks great Damian! It'd be even better if you write a test that ensures the updates are performed against the right database to prevent future regressions. I suggest you grep
the test directory for override_settings(DATABASE_ROUTERS
to get an idea of how you can route queries to the other
test database and use assertNumQueries(using='other')
to ensure it was properly routed.
comment:5 by , 3 years ago
Replying to Simon Charette:
You patch looks great Damian! It'd be even better if you write a test that ensures the updates are performed against the right database to prevent future regressions. I suggest you
grep
the test directory foroverride_settings(DATABASE_ROUTERS
to get an idea of how you can route queries to theother
test database and useassertNumQueries(using='other')
to ensure it was properly routed.
Thanks for the pointer, I've managed to sort out a regression test and have added it to my PR above. 👍
comment:6 by , 3 years ago
Needs tests: | unset |
---|---|
Triage Stage: | Accepted → Ready for checkin |
Thanks for the report.