Opened 6 months ago
Last modified 6 months ago
#36389 assigned Bug
GenericRelation uses read connection for writes
| Reported by: | Jake Howard | Owned by: | JaeHyuckSa |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 5.2 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | yes |
| Easy pickings: | no | UI/UX: | no |
Description
When trying to modify a GenericRelation (the other side of a GenericForeignKey) in a multi-DB environment the read connection ("replica") is used:
instance.relation.db # replica - CORRECT instance.relation.update(field="value") # also uses the replica - WRONG
This includes when explicitly requesting the "default" DB:
instance = MyModel.objects.using("default").first() instance.relation.update(field="value") # also uses the replica - WRONG
In cases where the db_for_read is read-only (common in HA environments), this produces an error.
I've created a minimal reproduction with a failing test to demo: https://github.com/RealOrangeOne/django-generic-relation-db-repro. I've tested this against Django 4.2 - 5.2.
I did some digging, and it seems to be something around the db property. Model.objects.update seems to correctly switch to the write instance, but I can't quite see where. My guess is that the generic relation needs to do the same, but the inheritance and dynamic classes makes it hard to trace.
Change History (5)
comment:1 by , 6 months ago
| Triage Stage: | Unreviewed → Accepted |
|---|---|
| Type: | Uncategorized → Bug |
comment:3 by , 6 months ago
| Owner: | set to |
|---|---|
| Status: | new → assigned |
comment:4 by , 6 months ago
| Has patch: | set |
|---|
comment:5 by , 6 months ago
| Patch needs improvement: | set |
|---|
Thank you for the test project!