-
Notifications
You must be signed in to change notification settings - Fork 49
Refetch computed for newly inserted objects #869
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
Conversation
963073a to
d36e8c0
Compare
d36e8c0 to
b753f12
Compare
b753f12 to
a4ac639
Compare
a4ac639 to
19fe9fa
Compare
309abbd to
0b99ffa
Compare
gel/_internal/_save.py
Outdated
| ref_shape.fields[field_name] = ptr_info | ||
|
|
||
| else: | ||
| # New objects only need computeds refetched |
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.
Wait, strictly speaking this isn't true and I'm not sure why we need this "optimization". Even new object's links can be rewritten by a trigger/mutation rewrites.
So the question is why do we need to bother and should we?
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 did this because the design says we should refetch all computed properties for new objects, but only set properties for existing objects.
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.
Probably part of the intended behaviour.
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.
Not by a trigger, but by a rewrite certainly. We probably do want to refetch all of them?
(Which design do you mean here?)
gel/_internal/_save.py
Outdated
|
|
||
| else: | ||
| # New objects only need computeds refetched | ||
| for field_name in obj.__pydantic_computed_fields__: |
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'd use pointer introspection here, not __pydantic_computed_fields__
| ) | ||
| for obj in shape.models: | ||
| link_ids = obj_links_all[obj.id] | ||
| link_ids = obj_links_all[self._get_id(obj)] |
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.
good catch
gel/_internal/_save.py
Outdated
|
|
||
| def __post_init__(self) -> None: | ||
| self.new_object_ids = {} | ||
| self.new_objects = {} |
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've changed the collection type for new_object_ids
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.
please rebase onto the fresh master
gel/_internal/_save.py
Outdated
| # see the above comment. | ||
| multi_prop_commit_recursive(linked) | ||
|
|
||
| if new_obj_id := self.new_object_ids.get(id(obj)): |
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.
yeah, rebase is needed. Basically with the latest master you'd just self.new_object_ids.get(obj)
86d8765 to
8eb33b0
Compare
8eb33b0 to
c2debad
Compare
929784c to
134a7a0
Compare
acdf183 to
dc41bdb
Compare
146db4c to
2297769
Compare
|
This now includes fixes for #884 |
2a162be to
4fcac61
Compare
| tp_pointers = tp_obj.__gel_reflection__.pointers | ||
| ref_shape = refetch_ops[tp_obj] | ||
| ref_shape.models.append(obj) | ||
| # Existing objects should refetch anything that was previously set |
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.
Not just existing objects, right? New objects too?
gel/_internal/_save.py
Outdated
| if ( | ||
| # prop not refetched | ||
| prop.name not in new_obj.__dict__ | ||
| # TODO: Refetching links for new objects |
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.
?
gel/_internal/_save.py
Outdated
| if ( | ||
| self.refetch | ||
| and obj in self.new_object_ids | ||
| and (new_obj_id := self.new_object_ids.get(obj)) | ||
| ): | ||
| new_obj = self.new_objects.get(new_obj_id) |
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.
What's going on here? Why does new_objects need a different path for updating the objects with refetched data than the old objects?
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.
There are 3 instances of the same object:
- the user instance
- the batch instance
- the refetch instance
New objects are updated differently from existing objects since they don't have an id to start with.
The sequence of operations:
Client._save_impl: Batch queries are run in the clientQueryBatch.record_inserted_data: batch instances saved innew_objectsand the relationship to the user instances is saved innew_object_ids.SaveExecutor._commit:- Computed props from the batch instance are applied to the user instance
apply_refetched_data: the batch instance is updated with the refetch instance's data_commit_recursive: the user instance is updated with the batch instance's data.
Step 3 has a lot of redundant work so I've simplified it to:
apply_refetched_data: the batch instance is updated with the refetch instance's data- Copy all refetched props to the user instance.
4fcac61 to
464610e
Compare
Given a schema
If a user does:
The order of inserts will be
a, thenband so the value ofa.total_valfetched during the insert will be 0.This PR adds a refetch query for the computed properties of newly inserted objects.
Tests are based on #848