Exposing control over return_values in Model.update() #1050
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
Currently, invoking
.update()
on a model will always read back the entire document from the DB with no option to override this behavior. If one's object is very large (e.g., contains long lists), one may not wish to receive everything (or anything at all) back after performing an update (e.g., in the common use case of a REST API handler). That's a use case for us at Intheon.DynamoDB has of course a feature for that, the ReturnValues request parameter (which can take the values
NONE
,ALL_NEW
,ALL_OLD
,UPDATED_NEW
andUPDATED_OLD
), and that feature is already exposed in PynamoDB, but so far only in the low-levelTableConnection.update_item()
method. Unfortunately, falling back to that in user code would require the user to duplicate some internal PynamoDB logic and/or to invoke non-public methods of the model, so it's not really an alternative that can be recommended.This PR
Currently,
Model.update()
simply hard-codes this value toALL_NEW
. This PR proposes to make that a new parameter instead, which can be overridden as initem.update(actions=[...], read_back=NONE)
to read nothing back from the DB. At this time, the PR is trivial and permits only eitherALL_NEW
(default, and equivalent to the current behavior) orNONE
, which reads nothing back and consequently returnsNone
and leaves the local item unaltered.I've pondered whether it should be called
return_values
instead, but that seems rather confusing to the user, who may assume that the flag affects only the return values of theupdate()
method, while the local item might still be updated in-place as usual. Calling itread_back
makes that clearer since it talks about what information comes back from the DB. That interpretation also holds up when in the future someone decides to add support for other DynamoDB modes likeALL_OLD
, in which case we'd expect that the local copy will be populated with whatever the DB state was before the update happened (rather than only the return value receiving the old data).While this PR is very simple, in the future someone could implement support for partial updates of the local record (via
UPDATED_NEW
), and this argument would allow the user to selectively choose one read-back mode or another, which would be an application-dependent choice (e.g., in the presence of concurrency), so there's some future-proofing in there.A unit test that checks these semantics is provided.