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

Multiple attrs update #194

Merged
merged 10 commits into from Nov 30, 2016

Conversation

yedpodtrzitko
Copy link
Contributor

@yedpodtrzitko yedpodtrzitko commented Nov 8, 2016

this allows to update multiple attributes at once using a new function Model.update (code based on the existing method Model.update_item()

This fixes #157 and #195

@coveralls
Copy link

Coverage Status

Coverage increased (+0.05%) to 97.816% when pulling 751c9da on yedpodtrzitko:multiple-attrs-update into ce741ab on jlafon:devel.

2 similar comments
@coveralls
Copy link

coveralls commented Nov 8, 2016

Coverage Status

Coverage increased (+0.05%) to 97.816% when pulling 751c9da on yedpodtrzitko:multiple-attrs-update into ce741ab on jlafon:devel.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.05%) to 97.816% when pulling 751c9da on yedpodtrzitko:multiple-attrs-update into ce741ab on jlafon:devel.

@coveralls
Copy link

coveralls commented Nov 8, 2016

Coverage Status

Coverage increased (+0.05%) to 97.816% when pulling 6da2455 on yedpodtrzitko:multiple-attrs-update into ce741ab on jlafon:devel.

3 similar comments
@coveralls
Copy link

Coverage Status

Coverage increased (+0.05%) to 97.816% when pulling 6da2455 on yedpodtrzitko:multiple-attrs-update into ce741ab on jlafon:devel.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.05%) to 97.816% when pulling 6da2455 on yedpodtrzitko:multiple-attrs-update into ce741ab on jlafon:devel.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.05%) to 97.816% when pulling 6da2455 on yedpodtrzitko:multiple-attrs-update into ce741ab on jlafon:devel.

@danielhochman
Copy link
Contributor

i think i'd prefer to move multiple update functionality to a method called update() and deprecate update_item(). update_item() never works how anyone would expect it to.

thoughts?

@yedpodtrzitko
Copy link
Contributor Author

yedpodtrzitko commented Nov 8, 2016

Ok, the code will be a wee bit simpler without the backward compatibility + I'll also try to implement a fix for #195 there.

@coveralls
Copy link

coveralls commented Nov 8, 2016

Coverage Status

Coverage decreased (-0.07%) to 97.702% when pulling cc4b9ea on yedpodtrzitko:multiple-attrs-update into ce741ab on jlafon:devel.

@coveralls
Copy link

coveralls commented Nov 8, 2016

Coverage Status

Coverage decreased (-0.07%) to 97.702% when pulling ae39b87 on yedpodtrzitko:multiple-attrs-update into ce741ab on jlafon:devel.

@yedpodtrzitko
Copy link
Contributor Author

@danielhochman

  • update() implemented (at least in the Model)
  • saving null value for attributes with null=True is now handled properly

let me know if you have any suggestions about the code. Otherwise I'll just add docs & it's good to go.

@@ -323,6 +323,8 @@ def update_item(self, attribute, value=None, action=None, conditional_operator=N
:param action: The action to take if this item already exists.
See: http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html#DDB-UpdateItem-request-AttributeUpdate
"""
DeprecationWarning("`Model.update_item` is deprecated in favour of `Model.update` now")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this do anything?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah! fixed.

@coveralls
Copy link

coveralls commented Nov 10, 2016

Coverage Status

Coverage decreased (-0.07%) to 97.703% when pulling d1f272e on yedpodtrzitko:multiple-attrs-update into ce741ab on jlafon:devel.

@@ -162,7 +166,7 @@
# These are the valid select values for the Scan operation
# See: http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html#DDB-Scan-request-Select
NOT_NULL = 'NOT_NULL'
NULL = 'NULL'
#NULL = 'NULL' # declared as a type above
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we just delete this maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can. The reason I've done it this way was if someone would be thinking 'so here NOT_NULL, but where's NULL?'

Fixed in the last commit.

@coveralls
Copy link

coveralls commented Nov 11, 2016

Coverage Status

Coverage decreased (-0.05%) to 97.716% when pulling 495f340 on yedpodtrzitko:multiple-attrs-update into ce741ab on jlafon:devel.

@coveralls
Copy link

coveralls commented Nov 14, 2016

Coverage Status

Coverage decreased (-0.05%) to 97.716% when pulling 70fe12e on yedpodtrzitko:multiple-attrs-update into ce741ab on jlafon:devel.


:param value: a value to serialize
"""
serialized = attr.serialize(value)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the passed value is already serialized on 1210 right?

we should either remove that or skip this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will require a few more changes (which I wanted to avoid), but I can give it a try.

if serialized is None:
if not attr.null:
raise ValueError("Attribute '{0}': cannot be None".format(attr.attr_name))
return {NULL: True}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we just set serialized = True and let the ATTR_TYPE_MAP on line 1286 handle the null bit? seems nicer maybe? don't really know tbh

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this is a fix for #195

kwargs['expected'] = self._build_expected_values(expected_values, UPDATE_FILTER_OPERATOR_MAP)

for attr, params in attributes.items():
attribute_cls = self._get_attributes()[attr]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might move the self._get_attributes() call outside the loop?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure


for attr, params in attributes.items():
attribute_cls = self._get_attributes()[attr]
action = params['action'] and params['action'].upper()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

won't this return a bool ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, either False (in case params['action'] is evaluated to False) or the value of the second statement)

>>> a = {'none': False, 'one': 'yes'}
>>> a['none'] and a['none'].upper()
False
>>> a['one'] and a['one'].upper()
'YES'

attribute_cls = self._get_attributes()[attr]
action = params['action'] and params['action'].upper()
attr_values = {ACTION: action}
if action != DELETE:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a test for DELETE

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

@coveralls
Copy link

coveralls commented Nov 17, 2016

Coverage Status

Coverage decreased (-0.2%) to 97.561% when pulling 2d89666 on yedpodtrzitko:multiple-attrs-update into ce741ab on jlafon:devel.

@coveralls
Copy link

coveralls commented Nov 17, 2016

Coverage Status

Coverage decreased (-0.03%) to 97.738% when pulling d0eb3c8 on yedpodtrzitko:multiple-attrs-update into ce741ab on jlafon:devel.

@@ -357,6 +361,52 @@ def update_item(self, attribute, value=None, action=None, conditional_operator=N
setattr(self, name, attr.deserialize(value.get(ATTR_TYPE_MAP[attr.attr_type])))
return data


def update(self, attributes, conditional_operator=None, **expected_values):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be better to take kwargs that map from the model_field_name to the new value? i see we've already got **expected_values filling that role though... maybe we could make that a keyword argument

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be good to do now since this is new...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jmphilli you might need to pass action for the attributes too. That would mean a bunch of small dictionaries like attribute_name={'value': 1, 'action': 'add'}.

else:
if attr.is_hash_key:
attrs[HASH] = serialized
attrs[HASH] = list(serialized.values())[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I replaced serialized = attr.serialize(value) above with _serialize_value() in order to avoid a double call of attr.serialize() you did not like (I could not remove it inside of serialize_value() since it's used elsewhere too)

Since _serialize_value() returns value in the DynamoDB serialization format (ie. {TYPE: VALUE}), I need to extract the value here.

List conversion is done because Python 3 does not support indexing of the type returned by values()

@coveralls
Copy link

coveralls commented Nov 18, 2016

Coverage Status

Coverage decreased (-0.03%) to 97.738% when pulling 2018285 on yedpodtrzitko:multiple-attrs-update into ce741ab on jlafon:devel.

@jmphilli
Copy link
Contributor

daniel is out for a week. i'll look at this again today, but i can only give my seal of approval which doesn't really do much for you unfortunately lol.

@yedpodtrzitko
Copy link
Contributor Author

np, I appreciate your feedback.

serialized = attr.serialize(value)
if serialized is None:

serialized = Model._serialize_value(attr, value, null_check)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self._serialize_value

action = params['action'] and params['action'].upper()
attr_values = {ACTION: action}
if action != DELETE:
attr_values[VALUE] = Model._serialize_value(attribute_cls, params['value'])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self._serialize_value

@coveralls
Copy link

coveralls commented Nov 23, 2016

Coverage Status

Coverage decreased (-0.04%) to 97.76% when pulling c56c8da on yedpodtrzitko:multiple-attrs-update into 3d986bb on jlafon:devel.

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

Successfully merging this pull request may close these issues.

None yet

4 participants