Ejemplo n.º 1
0
class Index(object):

    def __init__(self, db, config):
        self.db = db
        self.config = config
        self.es = Elasticsearch(
            hosts=self.config.hosts,
            **self.config.get("client_options", {})
        )

        self.types = AttributeDict()

        self._index = config.index

    def register(self, type_):
        obj = type_(self)
        self.types[obj._type] = obj

    def reindex(self, alias=True, keep_old=False):
        # Generate an Index Name for Warehouse
        index = "".join([
            self._index,
            binascii.hexlify(os.urandom(4)).decode("ascii"),
        ])

        # Create this index
        self.es.indices.create(index, {
            "mappings": {
                doc_type._type: doc_type.get_mapping()
                for doc_type in self.types.values()
            },
        })

        # Index everything into the new index
        for doc_type in self.types.values():
            doc_type.index_all(index=index)

        # Update the alias unless we've been told not to
        if alias:
            self.update_alias(self._index, index, keep_old=keep_old)

    def update_alias(self, alias, index, keep_old=False):
        # Get the old index from ElasticSearch
        try:
            old_index = list(self.es.indices.get_alias(self._index))[0]
        except TransportError as exc:
            if not exc.status_code == 404:
                raise
            old_index = None

        # Remove the alias to the old index if it exists
        if old_index is not None:
            actions = [{"remove": {"index": old_index, "alias": alias}}]
        else:
            actions = []

        # Add the alias to the new index
        actions += [{"add": {"index": index, "alias": alias}}]

        # Update To the New Index
        self.es.indices.update_aliases({"actions": actions})

        # Delete the old index if it exists and unless we're keeping it
        if not keep_old and old_index is not None:
            self.es.indices.delete(old_index)