Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plans supported by prefetch_related #27

Closed
hidaris opened this issue Oct 30, 2020 · 7 comments
Closed

Plans supported by prefetch_related #27

hidaris opened this issue Oct 30, 2020 · 7 comments
Labels
enhancement New feature or request

Comments

@hidaris
Copy link

hidaris commented Oct 30, 2020

prefetch_related is helpful in many situations, is there a plan to support it?

@collerek
Copy link
Owner

You have select_related that works for both ForeignKey and ManyToMany relations. It's fetching the related models in the same query (same db call) and populating the result with nested models.

@collerek
Copy link
Owner

Is this something you mean? Maybe the documentation is not clear, let me know.

@hidaris
Copy link
Author

hidaris commented Oct 30, 2020

I need to try it later. Yes, the documentation could be clearer, because in Django select_related and prefetch_related are different.

@collerek
Copy link
Owner

Ah yeah, I think I will add prefetch_related (unless you want to create a PR, always welcome).

Right now select_related works in line with django meaning that one join is created and one query is run -> later all related models are extracted and you get a main model with populated nested models.

The difference is that in django select_related can be used only on ForeignKey relation while select_related in ormar can be used on a relation, reverse relation (so virtual foreign key -> second side of the relation) and on many2many relation. But select_related returns a QuerySet and is only run after you issue all(), get() etc.

prefetch_related should be probably implemented in a way that it's an end point (like all() - needs to be awaited).

But even without prefetch_related you can load related models for two out of 3 relation types:

  • for related ForeignKey item you can load related model by await Model.related_name.load()
  • for ManyToMany items the relation exposes most of the QuerySet api, so you can run await Model.many_to_many_name.all()
  • currently there is no way to load reverse relation (second side of the ForeignKey). You can add and remove items, but this is not persisted in a database and no way to load items like this. Was planning to add save_related or something that will go through all nested models and save them if they are not saved yet (status of save is also not yet implemented)

Good idea, thanks.

@hidaris
Copy link
Author

hidaris commented Nov 4, 2020

Thanks for the detailed answer, but i can't post a pr yet because I'm not familiar with the ormar implementation, or can you explain in the dev docs the proper way to get into the project and contribute?

@collerek collerek added the enhancement New feature or request label Nov 11, 2020
@collerek
Copy link
Owner

OK, it took more time and was quite a lot more complicated than I initially thought but should be closed in #54.
In the end I decided to implement it working the same as django, so it's called exactly the same as select_related and returns a QuerySet.

It supports fields, exclude_fields and order_by QuerySet methods, others are called on the original/initial query anyway.

When select related and prefetch_related are called on the same related model always select_related prevails, as prefetch_related is called on a result returned from select_related.

More details in the docs.
Loading children of already loaded models will be handled in #50 (for reverse FK, other already working).

@hidaris
Copy link
Author

hidaris commented Nov 27, 2020

Wow, very efficient, can't wait to try it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants