-
Notifications
You must be signed in to change notification settings - Fork 9
Add max depth parameter to be able load nested relationships on a model #44
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
Add max depth parameter to be able load nested relationships on a model #44
Conversation
a4d4795 to
775190f
Compare
src/sqlservice/model.py
Outdated
| By default, only table columns will be included. To include relationship fields, set | ||
| ``include_relationships=True``. This will nest ``to_dict()`` calls to the relationship | ||
| models. | ||
| ``exclude_nested_relationships``: Exclude nested relationships. Defaults to ``False``. | ||
| ``include_nested_relationships``: Include nested relationships. Defaults to ``False``. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like I have some stale docs with references to include_relationships as a parameter and incorrect behavior description. Mind updating that to say something about how relationships are included by default but can be excluded with exclude_relationships=True? Can also add these new fields in the description as well but within the paragraph instead of as a separate line items.
src/sqlservice/model.py
Outdated
| exclude_nested_relationships: bool = False, | ||
| include_nested_relationships: bool = False, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think both of these are needed since they should be mutually exclusive (i.e. one wouldn't set exclude_nested_relationships=True and include_nested_relationships=True). If the default behavior is to include nested relationships, then should use exclude_nested_relationships but if the default behavior is to excluded nested relationships, then should use include_nested_relationships.
I'm leaning towards having the nested relationships excluded by default so would just have include_nested_relationships. Thought?
tests/test_model.py
Outdated
| "created_by_user": {"id": 1, "name": "n", "active": True}, | ||
| "updated_by_user": {"id": 2, "name": "n", "active": True}, | ||
| }, | ||
| id="circular_reference_lazy_loaded", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| id="circular_reference_lazy_loaded", | |
| id="exclude_nested_relationships_lazy_loaded_with_circular_reference", |
tests/test_model.py
Outdated
| ], | ||
| }, | ||
| }, | ||
| id="circular_reference_lazy_loaded_with_max_depth", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| id="circular_reference_lazy_loaded_with_max_depth", | |
| id="include_nested_relationships_lazy_loaded_with_circular_reference", |
| created_by_user=User(id=1, name="n"), | ||
| updated_by_user=User(id=2, name="n"), | ||
| ), | ||
| {"lazyload": True, "include_nested_relationships": True}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to also have tests without lazy-loading that verify that non-loaded nested relationships won't be included.
| title: Mapped[str] = mapped_column(sa.String()) | ||
| created_by: Mapped[int] = mapped_column(sa.Integer(), sa.ForeignKey("users.id"), nullable=False) | ||
| created_by_user: Mapped["User"] = relationship( | ||
| "User", foreign_keys=[created_by], back_populates="created_books" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For my own knowledge since I never really used back_populates: Is back_populates needed here when the corresponding field is explicitly defined in the other model? Could that argument be dropped from all the fields or is it needed? What's the behavior if it's left off?
dgilland
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some nits on organization and docstring wording.
src/sqlservice/model.py
Outdated
| exclude_relationships: bool = False, | ||
| lazyload: bool = False, | ||
| include_nested_relationships: bool = False, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Group relationship arguments together:
| exclude_relationships: bool = False, | |
| lazyload: bool = False, | |
| include_nested_relationships: bool = False, | |
| lazyload: bool = False, | |
| exclude_relationships: bool = False, | |
| include_nested_relationships: bool = False, |
src/sqlservice/model.py
Outdated
| By default, only table columns will be included. To exclude relationships, set | ||
| ``exclude_relationships=True``. | ||
| To include nested relationships, set ``include_nested_relationships=True``. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| By default, only table columns will be included. To exclude relationships, set | |
| ``exclude_relationships=True``. | |
| To include nested relationships, set ``include_nested_relationships=True``. | |
| By default, table columns and relationships will be included while nested relationships will be excluded. To exclude relationships, set ``exclude_relationships=True``. To include nested relationships, set ``include_nested_relationships=True``. |
| exclude_relationships=exclude_relationships, | ||
| lazyload=lazyload, | ||
| include_nested_relationships=include_nested_relationships, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Group relationship arguments together:
| exclude_relationships=exclude_relationships, | |
| lazyload=lazyload, | |
| include_nested_relationships=include_nested_relationships, | |
| lazyload=lazyload, | |
| exclude_relationships=exclude_relationships, | |
| include_nested_relationships=include_nested_relationships, |
src/sqlservice/model.py
Outdated
| exclude_relationships: bool = False, | ||
| lazyload: bool = False, | ||
| include_nested_relationships: bool = False, | ||
| ): | ||
| self.exclude_relationships = exclude_relationships | ||
| self.lazyload = lazyload | ||
| self.include_nested_relationships = include_nested_relationships |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Group relationship arguments together:
| exclude_relationships: bool = False, | |
| lazyload: bool = False, | |
| include_nested_relationships: bool = False, | |
| ): | |
| self.exclude_relationships = exclude_relationships | |
| self.lazyload = lazyload | |
| self.include_nested_relationships = include_nested_relationships | |
| lazyload: bool = False, | |
| exclude_relationships: bool = False, | |
| include_nested_relationships: bool = False, | |
| ): | |
| self.lazyload = lazyload | |
| self.exclude_relationships = exclude_relationships | |
| self.include_nested_relationships = include_nested_relationships |
Problem
to_dictmethod goes into recursion issue whenever we want to load all the nested relationshipsto_dictand the other doesn't load as the model is already inseenand is not going to be visited againGoal
ModelSerializer.to_dictmethod not loading multiple relationships with the same model #43Approach Taken
max_depthparameter which can help only load relationship upto a certain depthcachewhere we can store the model object based on theidvalue. So, when a model is already visited and if we want it again - we can load it up from the cache