-
Notifications
You must be signed in to change notification settings - Fork 95
service: fix navigation for associations with many to one relationships and for associations with relationships to same entity #223
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -874,16 +874,10 @@ def nav(self, nav_property): | |
| association_info.name, | ||
| association_info.namespace) | ||
|
|
||
| navigation_entity_set = None | ||
| for end in association_set.end_roles: | ||
| if association_set.end_by_entity_set(end.entity_set_name).role == navigation_property.to_role.role: | ||
| navigation_entity_set = self._service.schema.entity_set(end.entity_set_name, association_info.namespace) | ||
| end = association_set.end_by_role(navigation_property.to_role.role) | ||
| navigation_entity_set = self._service.schema.entity_set(end.entity_set_name) | ||
|
|
||
| if not navigation_entity_set: | ||
| raise PyODataException(f'No association set for role {navigation_property.to_role}') | ||
|
Comment on lines
-882
to
-883
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the bug is about "many to one relationships", why remove this exception rise? Even the second part of the PR description - "it is not possible to use the nav method with associations where both ends are of the same entity type." - as I understand it, the case that you would like to refer to something that does not exist at all is still valid. The exception rise is removed multiple times, line 1358 (original). As an example - consider metadata file, that is invalid, but forced to be parsed anyway - and then you can end easily with trying to access something which is not there at all. It bothers me a bit that there is not a test that would start to fail by removing these lines - that for specific input we expect this exception to be thrown. But if such test existed, this PR would be IMHO backward-incompatible change.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have removed this exception because the end_by_role method is raising a KeyError in case the end role was not found. I have thought about to handle the KeyError and raising the PyODataException, but this would be a bit redundant. However, due to the possible KeyError of end_by_role the navigation_entity_set can never be None (e.g. in case of an invalid metadata file) and the PyODataException would never be raised. |
||
|
|
||
| roles = navigation_property.association.end_roles | ||
| if all((role.multiplicity != model.EndRole.MULTIPLICITY_ZERO_OR_MORE for role in roles)): | ||
| if navigation_property.to_role.multiplicity != model.EndRole.MULTIPLICITY_ZERO_OR_MORE: | ||
| return NavEntityProxy(self, nav_property, navigation_entity_set.entity_type, {}) | ||
|
|
||
| return EntitySetProxy( | ||
|
|
@@ -1349,17 +1343,10 @@ def nav(self, nav_property, key): | |
| association_set = self._service.schema.association_set_by_association( | ||
| association_info.name) | ||
|
|
||
| navigation_entity_set = None | ||
| for end in association_set.end_roles: | ||
| if association_set.end_by_entity_set(end.entity_set_name).role == navigation_property.to_role.role: | ||
| navigation_entity_set = self._service.schema.entity_set(end.entity_set_name) | ||
|
|
||
| if not navigation_entity_set: | ||
| raise PyODataException( | ||
| f'No association set for role {navigation_property.to_role} {association_set.end_roles}') | ||
| end = association_set.end_by_role(navigation_property.to_role.role) | ||
| navigation_entity_set = self._service.schema.entity_set(end.entity_set_name) | ||
|
|
||
| roles = navigation_property.association.end_roles | ||
| if all((role.multiplicity != model.EndRole.MULTIPLICITY_ZERO_OR_MORE for role in roles)): | ||
| if navigation_property.to_role.multiplicity != model.EndRole.MULTIPLICITY_ZERO_OR_MORE: | ||
| return self._get_nav_entity(key, nav_property, navigation_entity_set) | ||
|
|
||
| return EntitySetProxy( | ||
|
|
||
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.
why was the for loop removed? Again, all tests are still passing, but this may be a problem of the test suite - that the loop was not covered so far, just simple cases around navigational properties.
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.
The loop is not necessary (anymore) because the end_by_role method of the association_set is "looping" over the association_set.end_roles using the generator expression here:
python-pyodata/pyodata/v2/model.py
Line 2163 in 9a72f93
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.
OK, that's true. And also, since now test metadata.xml contains multimple association sets ending to same end role (Customer), it is proven by tests.