def wrapper(*args, **kwargs): ret = func(*args, **kwargs) session = Session() # tmp session._model_changes = {} try: session.commit() except SQLAlchemyError as se: session.rollback() raise_server_exc(DATABASE_UNKNOWN_ERROR, exc=se) finally: session.close() return ret
def reindex(clear=False, progressive=False, batch_size=None): """Reindex all content; optionally clear index before. All is done in asingle transaction by default. :param clear: clear index content. :param progressive: don't run in a single transaction. :param batch_size: number of documents to process before writing to the index. Unused in single transaction mode. If `None` then all documents of same content type are written at once. """ index_service = get_service("indexing") adapted = index_service.adapted index = index_service.app_state.indexes["default"] session = Session(bind=db.session.get_bind(None, None), autocommit=True) session._model_changes = {} # please flask-sqlalchemy <= 1.0 indexed = set() cleared = set() if batch_size is not None: batch_size = int(batch_size) strategy = progressive_mode if progressive else single_transaction strategy = strategy(index, clear=clear, progressive=progressive, batch_size=batch_size) next(strategy) # starts generator for cls in sorted(index_service.app_state.indexed_classes, key=lambda c: c.__name__): current_object_type = cls._object_type() if not clear and current_object_type not in cleared: strategy.send(current_object_type) cleared.add(current_object_type) adapter = adapted.get(current_object_type) if not adapter or not adapter.indexable: continue name = cls.__name__ with session.begin(): query = session.query(cls).options(sa.orm.lazyload("*")) try: count = query.count() except Exception as e: current_app.logger.error( "Indexing error on class {}: {}".format(name, repr(e))) continue print("*" * 79) print("{}".format(name)) if count == 0: print("*" * 79) print("{}".format(name)) continue print("*" * 79) print("{}".format(name)) count_current = 0 with tqdm(total=count) as bar: for obj in query.yield_per(1000): if obj.object_type != current_object_type: # may happen if obj is a subclass and its parent class # is also indexable bar.update() continue object_key = obj.object_key if object_key in indexed: bar.update() continue document = index_service.get_document(obj, adapter) strategy.send(document) indexed.add(object_key) if batch_size is not None and (count_current % batch_size) == 0: bar.update() strategy.send(COMMIT) bar.update() if batch_size is None: strategy.send(COMMIT) strategy.send(COMMIT) try: strategy.send(STOP) except StopIteration: pass try: strategy.close() except StopIteration: pass