After scouring the documentation and various tutorials, I cannot figure out how to set or update an attribute on a dynamo Item that is a multi-valued data type (number or string set). I'm using boto (boto.dynamodb2, to be specific -- not boto.dynamodb).
Trying something like this (where 'id' is the hash key):
Item(Table('test'), data={'id': '123', 'content': 'test', 'list': [1,2,3,4]}).save()
Results in this error:
TypeError: Unsupported type "<type 'list'>" for value "[1, 2, 3, 4]"
I feel like this must be possible in boto.dynamodb2, but it's odd that I can't find any examples of people doing this. (Everyone is just setting number or string attributes, not number set or string set attributes.)
Any insight on this topic and how I might get this to work with boto would be very much appreciated! I'm guessing I'm overlooking something simple. Thanks!
Okay, we were able to figure this out on our own. The problem with my example above is that I'm using a list instead of a set. The value of a multi-value attribute MUST be a set.
For example, this works:
Item(Table('test'), data={'id': '123', 'content': 'test', 'list': set([1,2,3,4])}).save()
DnyamoDB now supports Dict/List directly. Boto doesn't have support for it yet, but it's a small patch until it's supported in production.
############################################################
# Patch Dynamizer to support dict/list
############################################################
from boto.dynamodb.types import Dynamizer, get_dynamodb_type
def _get_dynamodb_type(self, attr):
if isinstance(attr, dict):
return 'M'
if isinstance(attr, list):
return 'L'
return get_dynamodb_type(attr)
def _encode_m(self, attr):
result = {}
for k, v in attr.items():
result[k] = self.encode(v)
return result
def _decode_m(self, attr):
result = {}
for k, v in attr.items():
result[k] = self.decode(v)
return result
def _encode_l(self, attr):
return [self.encode(v) for v in attr]
def _decode_l(self, attr):
return [self.decode(v) for v in attr]
Dynamizer._get_dynamodb_type = _get_dynamodb_type
Dynamizer._encode_m = _encode_m
Dynamizer._decode_m = _decode_m
Dynamizer._encode_l = _encode_l
Dynamizer._decode_l = _decode_l
############################################################
# End patch Dynamizer to support dict/list
############################################################
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With