tortoise / tortoise/tortoise-orm
prefetch_related with one to one relation doesn't sets backward reference
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 5.6k
- Forks
- 516
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 9
Description
Describe the bug
For example, you have Parent and Child models, Child holds a OneToOneField reference to a Parent
When you select Parent with .prefetch_related("child"), you can access .child attribute, and it will has prefetched child, as it should be
But when you try to access .parent attribute of that child, it will be QuerySet instead of Parent
To Reproduce
import asyncio
import tortoise
class Parent(tortoise.Model):
id = tortoise.fields.IntField(pk=True)
child: tortoise.fields.BackwardOneToOneRelation['Child']
class Child(tortoise.Model):
parent = tortoise.fields.OneToOneField("app.Parent", related_name="child", pk=True)
async def main():
await tortoise.Tortoise.init(db_url="sqlite://:memory:", modules={"app": ["__main__"]})
await tortoise.Tortoise.generate_schemas()
parent = await Parent.create(id=1)
await Child.create(parent=parent)
parent = await Parent.get(id=1).prefetch_related("child")
print(parent.child) # <Child>
print(parent.child.parent) # <tortoise.queryset.QuerySet object at ...>
if __name__ == '__main__':
asyncio.run(main())
Expected behavior
Tortoise sets up a circular references between parent and child models
Additional context
Using latest Tortoise 0.19.3
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 by running the provided asyncio reproduction with Parent, Child, and Parent.get(id=1).prefetch_related("child") to trace how the prefetch_related entry point assigns relations. Check the related OneToOneField and BackwardOneToOneRelation handling. Done means parent.child.parent resolves to the prefetched Parent rather than a QuerySet, with regression coverage for the example.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- database
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100