Fix whooshalchemy

Whooshalchemy was adding an event every time a new db session was
created, thus increasing a lot the computation time at each new call.

This is now fixed, and is a partial fix for #43.
This commit is contained in:
Lucas Verney 2017-05-05 11:04:29 +02:00
parent a5aeadef86
commit e0f8434877
3 changed files with 12 additions and 21 deletions

View File

@ -46,6 +46,12 @@ def init_db(database_uri=None, search_db_uri=None):
BASE.metadata.create_all(engine, checkfirst=True) BASE.metadata.create_all(engine, checkfirst=True)
Session = sessionmaker(bind=engine) # pylint: disable=locally-disabled,invalid-name Session = sessionmaker(bind=engine) # pylint: disable=locally-disabled,invalid-name
if search_db_uri:
index_service = IndexService(
whoosh_base=search_db_uri
)
index_service.register_class(flatisfy.models.flat.Flat)
@contextmanager @contextmanager
def get_session(): def get_session():
# pylint: disable=locally-disabled,line-too-long # pylint: disable=locally-disabled,line-too-long
@ -57,12 +63,6 @@ def init_db(database_uri=None, search_db_uri=None):
""" """
# pylint: enable=line-too-long,locally-disabled # pylint: enable=line-too-long,locally-disabled
session = Session() session = Session()
if search_db_uri:
index_service = IndexService(
whoosh_base=search_db_uri,
session=session
)
index_service.register_class(flatisfy.models.flat.Flat)
try: try:
yield session yield session
session.commit() session.commit()

View File

@ -31,8 +31,7 @@ from whoosh.qparser import MultifieldParser
class IndexService(object): class IndexService(object):
def __init__(self, config=None, session=None, whoosh_base=None): def __init__(self, config=None, whoosh_base=None):
self.session = session
if not whoosh_base and config: if not whoosh_base and config:
whoosh_base = config.get("WHOOSH_BASE") whoosh_base = config.get("WHOOSH_BASE")
if not whoosh_base: if not whoosh_base:
@ -60,8 +59,7 @@ class IndexService(object):
index = whoosh.index.create_in(index_path, schema) index = whoosh.index.create_in(index_path, schema)
self.indexes[model_class.__name__] = index self.indexes[model_class.__name__] = index
model_class.search_query = Searcher(model_class, primary, index, model_class.search_query = Searcher(model_class, primary, index)
self.session)
return index return index
def index_for_model_class(self, model_class): def index_for_model_class(self, model_class):
@ -118,7 +116,6 @@ class IndexService(object):
we update the whoosh index for the model. If no index exists, it will be we update the whoosh index for the model. If no index exists, it will be
created here; this could impose a penalty on the initial commit of a model. created here; this could impose a penalty on the initial commit of a model.
""" """
for typ, values in self.to_update.items(): for typ, values in self.to_update.items():
model_class = values[0][1].__class__ model_class = values[0][1].__class__
index = self.index_for_model_class(model_class) index = self.index_for_model_class(model_class)
@ -152,21 +149,15 @@ class Searcher(object):
Assigned to a Model class as ``search_query``, which enables text-querying. Assigned to a Model class as ``search_query``, which enables text-querying.
""" """
def __init__(self, model_class, primary, index, session=None): def __init__(self, model_class, primary, index):
self.model_class = model_class self.model_class = model_class
self.primary = primary self.primary = primary
self.index = index self.index = index
self.session = session
self.searcher = index.searcher() self.searcher = index.searcher()
fields = set(index.schema._fields.keys()) - set([self.primary]) fields = set(index.schema._fields.keys()) - set([self.primary])
self.parser = MultifieldParser(list(fields), index.schema) self.parser = MultifieldParser(list(fields), index.schema)
def __call__(self, query, limit=None): def __call__(self, session, query, limit=None):
session = self.session
# When using Flask, get the session from the query attached to the model class.
if not session:
session = self.model_class.query.session
results = self.index.searcher().search( results = self.index.searcher().search(
self.parser.parse(query), limit=limit) self.parser.parse(query), limit=limit)

View File

@ -220,7 +220,7 @@ def time_to_places_v1(config):
} }
def search_v1(config): def search_v1(db, config):
""" """
API v1 route to perform a fulltext search on flats. API v1 route to perform a fulltext search on flats.
@ -238,7 +238,7 @@ def search_v1(config):
except (ValueError, KeyError): except (ValueError, KeyError):
return bottle.HTTPError(400, "Invalid query provided.") return bottle.HTTPError(400, "Invalid query provided.")
flats_db_query = flat_model.Flat.search_query(query) flats_db_query = flat_model.Flat.search_query(db, query)
flats = [ flats = [
flat.json_api_repr() flat.json_api_repr()
for flat in flats_db_query for flat in flats_db_query