def do_updateitem(self, args): table_spec = self.tables[args['TableName']] sql_table = table_spec['sql_table'] key_spec = table_spec['key_spec'] table_def = table_spec['table_def'] if 'Expected' in args: raise NotImplementedError if args.get('ReturnValues') not in (None, 'ALL_OLD', 'ALL_NEW'): raise NotImplementedError if table_def.range_key: key = (utils.parse_value(args['Key']['HashKeyElement']), utils.parse_value(args['Key']['RangeKeyElement'])) expr = sql.and_(sql_table.c.hash_key == key[0], sql_table.c.range_key == key[1]) else: key = (utils.parse_value(args['Key']['HashKeyElement']), ) expr = sql_table.c.hash_key == key[0] # Update is one of our few transactionally important operations. By # setting self.connection, our callees should use that rather than the # connectionless self.engine method, allowing us to control the # transaction directly. self.connection = self.engine.connect() txn = self.connection.begin() q = sql.select([sql_table], expr) res = list(self.connection.execute(q)) if res: item = json.loads(res[0][sql_table.c.content]) else: item = {} item.update(utils.format_key(key_spec, key)) real_item = utils.parse_item(item) # Apply our updates for attribute, value_update in args['AttributeUpdates'].iteritems(): if value_update['Action'] == "ADD": if attribute in real_item: if isinstance(real_item[attribute], (int, float, list)): real_item[attribute] += utils.parse_value( value_update['Value']) elif isinstance(real_item[attribute], list): if hasattr(value_update['Value'], '__iter__'): real_item[attribute] += [ utils.parse_value(v) for v in value_update['Value'] ] else: real_item[attribute].append( utils.parse_value(value_update['Value'])) else: real_item[attribute].append( utils.parse_value(value_update['Value'])) else: real_item[attribute] = utils.parse_value( value_update['Value']) elif value_update['Action'] == "PUT": real_item[attribute] = utils.parse_value(value_update['Value']) elif value_update['Action'] == "DELETE": if attribute in real_item: del real_item[attribute] else: raise ValueError(value_update['Action']) # write to the db self._put_item(args['TableName'], utils.format_item(real_item)) txn.commit() self.connection = None if args.get('ReturnValues', 'NONE') == 'NONE': return {} elif args['ReturnValues'] == 'ALL_NEW': return {'Attributes': utils.format_item(real_item)} elif args['ReturnValues'] == 'ALL_OLD': return {'Attributes': item}
def test_multi_number_float(self): key = utils.format_key(('user', 'id'), ('Rhett', 123.123)) assert_equal(key, {'user': {'S': 'Rhett'}, 'id': {'N': '123.123'}})
def do_updateitem(self, args): table_spec = self.tables[args['TableName']] sql_table = table_spec['sql_table'] key_spec = table_spec['key_spec'] table_def = table_spec['table_def'] if 'Expected' in args: raise NotImplementedError if args.get('ReturnValues') not in (None, 'ALL_OLD', 'ALL_NEW'): raise NotImplementedError if table_def.range_key: key = (utils.parse_value(args['Key']['HashKeyElement']), utils.parse_value(args['Key']['RangeKeyElement'])) expr = sql.and_(sql_table.c.hash_key == key[0], sql_table.c.range_key == key[1]) else: key = (utils.parse_value(args['Key']['HashKeyElement']),) expr = sql_table.c.hash_key == key[0] # Update is one of our few transactionally important operations. By # setting self.connection, our callees should use that rather than the # connectionless self.engine method, allowing us to control the # transaction directly. self.connection = self.engine.connect() txn = self.connection.begin() q = sql.select([sql_table], expr) res = list(self.connection.execute(q)) if res: item = json.loads(res[0][sql_table.c.content]) else: item = {} item.update(utils.format_key(key_spec, key)) real_item = utils.parse_item(item) # Apply our updates for attribute, value_update in args['AttributeUpdates'].iteritems(): if value_update['Action'] == "ADD": if attribute in real_item: if isinstance(real_item[attribute], (int,float,list)): real_item[attribute] += utils.parse_value(value_update['Value']) elif isinstance(real_item[attribute], list): if hasattr(value_update['Value'], '__iter__'): real_item[attribute] += [utils.parse_value(v) for v in value_update['Value']] else: real_item[attribute].append(utils.parse_value(value_update['Value'])) else: real_item[attribute].append(utils.parse_value(value_update['Value'])) else: real_item[attribute] = utils.parse_value(value_update['Value']) elif value_update['Action'] == "PUT": real_item[attribute] = utils.parse_value(value_update['Value']) elif value_update['Action'] == "DELETE": if attribute in real_item: del real_item[attribute] else: raise ValueError(value_update['Action']) # write to the db self._put_item(args['TableName'], utils.format_item(real_item)) txn.commit() self.connection = None if args.get('ReturnValues', 'NONE') == 'NONE': return {} elif args['ReturnValues'] == 'ALL_NEW': return {'Attributes': utils.format_item(real_item)} elif args['ReturnValues'] == 'ALL_OLD': return {'Attributes': item}
def test_multi_string(self): key = utils.format_key(('user', 'id'), ('Rhett', 'foo')) assert_equal(key, {'user': {'S': 'Rhett'}, 'id': {'S': 'foo'}})
def test_single_string(self): key = utils.format_key(('user',), ('Rhett',)) assert_equal(key, {'user': {'S': 'Rhett'}})
def test_single_string(self): key = utils.format_key(('user', ), ('Rhett', )) assert_equal(key, {'user': {'S': 'Rhett'}})