def get_indexes(all_indexes):
    indexes = []
    global_indexes = []
    for index in all_indexes:
        name = index['name']
        schema = get_schema_param(index.get('hash_key_name'), index.get('hash_key_type'), index.get('range_key_name'), index.get('range_key_type'))
        throughput = {
            'read': index.get('read_capacity', 1),
            'write': index.get('write_capacity', 1)
        }

        if index['type'] == 'all':
            indexes.append(AllIndex(name, parts=schema))

        elif index['type'] == 'global_all':
            global_indexes.append(GlobalAllIndex(name, parts=schema, throughput=throughput))

        elif index['type'] == 'global_include':
            global_indexes.append(GlobalIncludeIndex(name, parts=schema, throughput=throughput, includes=index['includes']))

        elif index['type'] == 'global_keys_only':
            global_indexes.append(GlobalKeysOnlyIndex(name, parts=schema, throughput=throughput))

        elif index['type'] == 'include':
            indexes.append(IncludeIndex(name, parts=schema, includes=index['includes']))

        elif index['type'] == 'keys_only':
            indexes.append(KeysOnlyIndex(name, parts=schema))

    return indexes, global_indexes
Beispiel #2
0
    def test_gsi_with_just_hash_key(self):
        # GSI allows for querying off of different keys. This is behavior we
        # previously disallowed (due to standard & LSI queries).
        # See https://forums.aws.amazon.com/thread.jspa?threadID=146212&tstart=0
        users = Table.create('gsi_query_users',
                             schema=[HashKey('user_id')],
                             throughput={
                                 'read': 5,
                                 'write': 3,
                             },
                             global_indexes=[
                                 GlobalIncludeIndex(
                                     'UsernameIndex',
                                     parts=[
                                         HashKey('username'),
                                     ],
                                     includes=['user_id', 'username'],
                                     throughput={
                                         'read': 3,
                                         'write': 1,
                                     })
                             ])
        self.addCleanup(users.delete)

        # Wait for it.
        time.sleep(60)

        users.put_item(
            data={
                'user_id': '7',
                'username': '******',
                'first_name': 'John',
                'last_name': 'Doe',
            })
        users.put_item(
            data={
                'user_id': '24',
                'username': '******',
                'first_name': 'Alice',
                'last_name': 'Expert',
            })
        users.put_item(
            data={
                'user_id': '35',
                'username': '******',
                'first_name': 'Jane',
                'last_name': 'Doe',
            })

        # Try the main key. Should be fine.
        rs = users.query_2(user_id__eq='24')
        results = sorted([user['username'] for user in rs])
        self.assertEqual(results, ['alice'])

        # Now try the GSI. Also should work.
        rs = users.query_2(username__eq='johndoe', index='UsernameIndex')
        results = sorted([user['username'] for user in rs])
        self.assertEqual(results, ['johndoe'])
Beispiel #3
0
    def table_schema_call(self, target, cls):
        """Perform a table schema call.

        We call the callable target with the args and keywords needed for the
        table defined by cls. This is how we centralize the Table.create and
        Table ctor calls.
        """
        index_defs = []
        for name in cls.index_names() or []:
            index_defs.append(
                GlobalIncludeIndex(gsi_name(name),
                                   parts=[HashKey(name)],
                                   includes=['value']))

        return target(cls.get_table_name(),
                      connection=get_conn(),
                      schema=[HashKey('id')],
                      global_indexes=index_defs or None)
Beispiel #4
0
def _extract_index(index_data, global_index=False):
    '''
    Instantiates and returns an AllIndex object given a valid index
    configuration
    '''
    parsed_data = {}
    keys = []

    for key, value in six.iteritems(index_data):
        for item in value:
            for field, data in six.iteritems(item):
                if field == 'hash_key':
                    parsed_data['hash_key'] = data
                elif field == 'hash_key_data_type':
                    parsed_data['hash_key_data_type'] = data
                elif field == 'range_key':
                    parsed_data['range_key'] = data
                elif field == 'range_key_data_type':
                    parsed_data['range_key_data_type'] = data
                elif field == 'name':
                    parsed_data['name'] = data
                elif field == 'read_capacity_units':
                    parsed_data['read_capacity_units'] = data
                elif field == 'write_capacity_units':
                    parsed_data['write_capacity_units'] = data
                elif field == 'includes':
                    parsed_data['includes'] = data
                elif field == 'keys_only':
                    parsed_data['keys_only'] = True

    if parsed_data['hash_key']:
        keys.append(
            HashKey(parsed_data['hash_key'],
                    data_type=parsed_data['hash_key_data_type']))
    if parsed_data.get('range_key'):
        keys.append(
            RangeKey(parsed_data['range_key'],
                     data_type=parsed_data['range_key_data_type']))
    if (global_index and parsed_data['read_capacity_units']
            and parsed_data['write_capacity_units']):
        parsed_data['throughput'] = {
            'read': parsed_data['read_capacity_units'],
            'write': parsed_data['write_capacity_units']
        }
    if parsed_data['name'] and len(keys) > 0:
        if global_index:
            if parsed_data.get('keys_only') and parsed_data.get('includes'):
                raise SaltInvocationError(
                    'Only one type of GSI projection can be used.')

            if parsed_data.get('includes'):
                return GlobalIncludeIndex(parsed_data['name'],
                                          parts=keys,
                                          throughput=parsed_data['throughput'],
                                          includes=parsed_data['includes'])
            elif parsed_data.get('keys_only'):
                return GlobalKeysOnlyIndex(
                    parsed_data['name'],
                    parts=keys,
                    throughput=parsed_data['throughput'],
                )
            else:
                return GlobalAllIndex(parsed_data['name'],
                                      parts=keys,
                                      throughput=parsed_data['throughput'])
        else:
            return AllIndex(parsed_data['name'], parts=keys)
def extract_index(index_data, global_index=False):
    """
    Instantiates and returns an AllIndex object given a valid index
    configuration

    CLI Example:

    .. code-block:: bash

        salt myminion boto_dynamodb.extract_index index
    """
    parsed_data = {}
    keys = []

    for key, value in index_data.items():
        for item in value:
            for field, data in item.items():
                if field == "hash_key":
                    parsed_data["hash_key"] = data
                elif field == "hash_key_data_type":
                    parsed_data["hash_key_data_type"] = data
                elif field == "range_key":
                    parsed_data["range_key"] = data
                elif field == "range_key_data_type":
                    parsed_data["range_key_data_type"] = data
                elif field == "name":
                    parsed_data["name"] = data
                elif field == "read_capacity_units":
                    parsed_data["read_capacity_units"] = data
                elif field == "write_capacity_units":
                    parsed_data["write_capacity_units"] = data
                elif field == "includes":
                    parsed_data["includes"] = data
                elif field == "keys_only":
                    parsed_data["keys_only"] = True

    if parsed_data["hash_key"]:
        keys.append(
            HashKey(parsed_data["hash_key"],
                    data_type=parsed_data["hash_key_data_type"]))
    if parsed_data.get("range_key"):
        keys.append(
            RangeKey(parsed_data["range_key"],
                     data_type=parsed_data["range_key_data_type"]))
    if global_index and parsed_data["read_capacity_units"] and parsed_data[
            "write_capacity_units"]:
        parsed_data["throughput"] = {
            "read": parsed_data["read_capacity_units"],
            "write": parsed_data["write_capacity_units"],
        }
    if parsed_data["name"] and keys:
        if global_index:
            if parsed_data.get("keys_only") and parsed_data.get("includes"):
                raise SaltInvocationError(
                    "Only one type of GSI projection can be used.")

            if parsed_data.get("includes"):
                return GlobalIncludeIndex(
                    parsed_data["name"],
                    parts=keys,
                    throughput=parsed_data["throughput"],
                    includes=parsed_data["includes"],
                )
            elif parsed_data.get("keys_only"):
                return GlobalKeysOnlyIndex(
                    parsed_data["name"],
                    parts=keys,
                    throughput=parsed_data["throughput"],
                )
            else:
                return GlobalAllIndex(
                    parsed_data["name"],
                    parts=keys,
                    throughput=parsed_data["throughput"],
                )
        else:
            return AllIndex(parsed_data["name"], parts=keys)