MongoEngine / MongoEngine/mongoengine
.select_related() doesn't fetch `ReferenceField`
Open
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 4.3k
- Forks
- 1.2k
- Avg merge
- 4h 41m
- Merged PRs (30d)
- 11
Description
If you have multiple ReferenceFields to the same model – .select_related() doesn't fetch all the references it's supposed to.
This was also brought up in PR #1226, I believe.
Here's a test that shows the behavior (from the same PR):
def test_select_related_follows_referencefields(self):
class Human(Document):
pass
class Car(Document):
owner = ReferenceField(Human)
class ParkingSlot(Document):
owner = ReferenceField(Human)
car = ReferenceField(Car)
Human.drop_collection()
Car.drop_collection()
ParkingSlot.drop_collection()
for _ in range(24):
owner = Human.objects.create()
car = Car.objects.create(owner=owner)
ParkingSlot.objects.create(owner=owner, car=car)
with query_counter() as q:
self.assertEqual(q, 0)
parking_slots = ParkingSlot.objects.select_related(max_depth=2)
self.assertEqual(q, 3)
for parking_slot in parking_slots:
parking_slot.owner
parking_slot.car.owner
self.assertEqual(q, 3) # <-- q is 27 here!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the provided test_select_related_follows_referencefields scenario and the select_related(max_depth=2) entry point. Reproduce the query-count failure with multiple ReferenceFields, then make the test pass so accessing parking_slot.owner and parking_slot.car.owner performs no additional queries beyond the initial three.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- mongodb, python
- Domain
- database
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100