def serialize(self): """ Serialize a DynamoModel subclass to JSON that can be inserted into DynamoDB. Internally converts float to Decimal. Returns ------- dict of (str, Any) The serialized JSON entry """ model_attrs = type(self)._dynamodb_attributes() result = {} for dynamo_name, model_name in model_attrs.items(): value = getattr(self, model_name) if value is not NOT_SET: if type(value) in [list, set, tuple]: value = type(value)(to_decimal(v) for v in value) elif type(value) is dict: value = { to_decimal(k): to_decimal(v) for k, v in value.items() } else: value = to_decimal(value) result[dynamo_name] = value return result
def serialize_operand(value): name = str(uuid.uuid4())[:8] if isinstance(value, UpdateOperand): return value.serialize() elif isinstance(value, BaseAttribute): return itemize_attr(value) elif type(value) in [list, set, tuple]: name = ":" + name value = type(value)([to_decimal(v) for v in value]) return { "UpdateExpression": name, "ExpressionAttributeNames": {}, "ExpressionAttributeValues": { name: value }, } else: name = ":" + name return { "UpdateExpression": name, "ExpressionAttributeNames": {}, "ExpressionAttributeValues": { name: to_decimal(value) }, }
def _get_primary_key(self, key): if isinstance(key, dict): key = {k: to_decimal(v) for k, v in key.items()} primary_key = key else: table_description = self._dynamodb.client.describe_table( TableName=self.name, ) (partition_key,) = [ entry["AttributeName"] for entry in table_description["Table"]["KeySchema"] if entry["KeyType"] == "HASH" ] if isinstance(key, tuple): (sort_key,) = [ entry["AttributeName"] for entry in table_description["Table"]["KeySchema"] if entry["KeyType"] == "RANGE" ] primary_key = { partition_key: to_decimal(key[0]), sort_key: to_decimal(key[1]), } else: primary_key = {partition_key: to_decimal(key)} return primary_key
def between(self, low, high): """ Filter results by range (inclusive) Parameters ---------- low : Any Low end of the range high : Any High end of the range """ return self._query_type(self._awstin_name).between( to_decimal(low), to_decimal(high), )
def attribute_type(self, value): """ Filter results by attribute type Parameters ---------- value : str Index for a DynamoDB attribute type (e.g. "N" for Number) """ return BotoAttr(self._awstin_name).attribute_type(to_decimal(value))
def begins_with(self, value): """ Filter results by a key or attribute beginning with a value Parameters ---------- value : str Starting string for returned results """ return self._query_type(self._awstin_name).begins_with( to_decimal(value))
def in_(self, values): """ Filter results by existence in a set Parameters ---------- values : list of Any Allowed values of returned results """ in_values = [to_decimal(value) for value in values] return BotoAttr(self._awstin_name).is_in(in_values)
def contains(self, value): """ Filter results by attributes that are containers and contain the target value Parameters ---------- values : Any Result must contain this item """ return BotoAttr(self._awstin_name).contains(to_decimal(value))
def __ge__(self, value): return self._query_type(self._awstin_name).gte(to_decimal(value))
def __eq__(self, value): return self._query_type(self._awstin_name).eq(to_decimal(value))
def __ne__(self, value): return BotoAttr(self._awstin_name).ne(to_decimal(value))