Exemplo n.º 1
0
    def create_dynamo_schema(self, connection, tablenames=None, test=False,
                             wait=False, throughput=None):
        """
        Create all Dynamo tables for this model

        Parameters
        ----------
        connection : :class:`~boto.dynamodb2.layer1.DynamoDBConnection`
        tablenames : list, optional
            List of tables that already exist. Will call 'describe' if not
            provided.
        test : bool, optional
            If True, don't actually create the table (default False)
        wait : bool, optional
            If True, block until table has been created (default False)
        throughput : dict, optional
            The throughput of the table and global indexes. Has the keys 'read'
            and 'write'. To specify throughput for global indexes, add the name
            of the index as a key and another 'read', 'write' dict as the
            value.

        Returns
        -------
        table : str
            Table name that was created, or None if nothing created

        """
        if self.abstract:
            return None
        if tablenames is None:
            tablenames = connection.list_tables()['TableNames']
        if self.ddb_tablename in tablenames:
            return None
        elif test:
            return self.ddb_tablename

        attrs = []
        indexes = []
        global_indexes = []
        hash_key = None
        raw_attrs = {}

        if throughput is not None:
            table_throughput = throughput
        else:
            table_throughput = self.throughput
        table_throughput = {
            'ReadCapacityUnits': table_throughput['read'],
            'WriteCapacityUnits': table_throughput['write'],
        }

        hash_key = HashKey(self.hash_key.name,
                           data_type=self.hash_key.ddb_data_type)
        schema = [hash_key.schema()]
        for name, field in self.fields.iteritems():
            if field.hash_key:
                f = hash_key
            elif field.range_key:
                f = RangeKey(name, data_type=field.ddb_data_type)
                schema.append(f.schema())
            elif field.index:
                idx = field.get_boto_index(hash_key)
                f = idx.parts[1]
                indexes.append(idx.schema())
            elif any(map(lambda x: name in x, self.global_indexes)):
                f = BaseSchemaField(name, data_type=field.ddb_data_type)
            else:
                continue
            attrs.append(f.definition())
            raw_attrs[name] = f

        for gindex in self.global_indexes:
            index = gindex.get_boto_index(self.fields)
            if throughput is not None and gindex.name in throughput:
                index.throughput = throughput[gindex.name]
            global_indexes.append(index.schema())

        # Make sure indexes & global indexes either have data or are None
        indexes = indexes or None
        global_indexes = global_indexes or None
        if not test:
            connection.create_table(
                attrs, self.ddb_tablename, schema, table_throughput,
                local_secondary_indexes=indexes,
                global_secondary_indexes=global_indexes)
            if wait:
                desc = connection.describe_table(self.ddb_tablename)
                while desc['Table']['TableStatus'] != 'ACTIVE':
                    time.sleep(1)
                    desc = connection.describe_table(self.ddb_tablename)

        return self.ddb_tablename