Exemple #1
0
 def update_item(self,
                 key,
                 attribute_updates=None,
                 expected=None,
                 conditional_operator=None,
                 return_values=None,
                 return_consumed_capacity=None,
                 return_item_collection_metrics=None,
                 update_expression=None,
                 condition_expression=None,
                 expression_attribute_names=None,
                 expression_attribute_values=None):
     """Update item low-level method.
        Warning: support is very limited, only for counter updates
     """
     dyn = Dynamizer()
     # print update_expression, expression_attribute_values
     for name in key:
         key[name] = dyn.decode(key[name])
     item = self.get_item(**key)
     # expression is like SET a = a + :a SET b = b + :b'
     try:
         key, val = update_expression.split('=')[1].split('+')
     except IndexError:
         raise Exception('Table.update_item is limited to counter updates, '
                         'expressions like SET a = a + :val')
     key, val = key.strip(), val.strip()
     if expression_attribute_names and key in expression_attribute_names:
         key = expression_attribute_names[key]
     val = expression_attribute_values[val]
     item[dyn.decode(key)] += dyn.decode(val)
     item.save()
Exemple #2
0
    def use_decimals(self):
        """
        Use the ``decimal.Decimal`` type for encoding/decoding numeric types.

        By default, ints/floats are used to represent numeric types
        ('N', 'NS') received from DynamoDB.  Using the ``Decimal``
        type is recommended to prevent loss of precision.

        """
        # Eventually this should be made the default dynamizer.
        self.dynamizer = Dynamizer()
Exemple #3
0
def build_condition(filter_map, using=CONDITIONS):
    """ Implement the conditions described in
    docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html

    """
    if not filter_map:
        return

    filters = {}
    dynamizer = Dynamizer()

    for field_and_op, value in filter_map.items():
        field_bits = field_and_op.split('__')
        fieldname = '__'.join(field_bits[:-1])

        try:
            op = using[field_bits[-1]]
        except KeyError:
            raise ConditionNotRecognizedException(
                "Operator '%s' from '%s' is not recognized." %
                (field_bits[-1], field_and_op))

        lookup = {
            'AttributeValueList': [],
            'ComparisonOperator': op,
        }

        # Special-case the ``NULL/NOT_NULL`` case.
        if field_bits[-1] == 'null':
            del lookup['AttributeValueList']

            if value is False:
                lookup['ComparisonOperator'] = 'NOT_NULL'
            else:
                lookup['ComparisonOperator'] = 'NULL'
        # Special-case the ``BETWEEN`` case.
        elif field_bits[-1] == 'between':
            if len(value) == 2 and isinstance(value, (list, tuple)):
                lookup['AttributeValueList'].append(dynamizer.encode(value[0]))
                lookup['AttributeValueList'].append(dynamizer.encode(value[1]))
        # Special-case the ``IN`` case
        elif field_bits[-1] == 'in':
            for val in value:
                lookup['AttributeValueList'].append(dynamizer.encode(val))
        else:
            # Fix up the value for encoding, because it was built to only work
            # with ``set``s.
            if isinstance(value, (list, tuple)):
                value = set(value)
            lookup['AttributeValueList'].append(dynamizer.encode(value))

        # Finally, insert it into the filters.
        filters[fieldname] = lookup
    return filters
Exemple #4
0
 def update_counter(self, hashkey, rangekey=None, **kwargs):
     dyn = Dynamizer()
     counter = list(kwargs.keys())[0]
     inc = list(kwargs.values())[0]
     connection = self.db.get_connection()
     keys = self._get_keys_dict(hashkey, rangekey)
     for key in keys:
         keys[key] = dyn.encode(keys[key])
     self.db.get_connection().update_item(
         table_name=self.db.get_table_name(self.table_name),
         key=keys,
         update_expression="SET #counter = #counter + :inc",
         expression_attribute_names={'#counter': counter},
         expression_attribute_values={':inc': dyn.encode(kwargs[counter])},
         return_values="UPDATED_NEW")
Exemple #5
0
 def _encode(self, value):
     return Dynamizer().encode(value)
Exemple #6
0
 def decode(self, value):
     return Dynamizer().decode(value)
Exemple #7
0
 def __init__(self):
     self.data = {}
     self._dynamizer = Dynamizer()
     self._current_key = 1