Commit d0f63e8e authored by Serge S. Koval's avatar Serge S. Koval

Merge pull request #198 from brAzzi64/row_count_performance

Fix for performance issue when calculating total row count for paging
parents 2fd4880a 45a27235
...@@ -3,7 +3,7 @@ import logging ...@@ -3,7 +3,7 @@ import logging
from sqlalchemy.orm.attributes import InstrumentedAttribute from sqlalchemy.orm.attributes import InstrumentedAttribute
from sqlalchemy.orm import subqueryload from sqlalchemy.orm import subqueryload
from sqlalchemy.sql.expression import desc from sqlalchemy.sql.expression import desc
from sqlalchemy import or_, Column from sqlalchemy import or_, Column, func
from flask import flash from flask import flash
...@@ -573,6 +573,12 @@ class ModelView(BaseModelView): ...@@ -573,6 +573,12 @@ class ModelView(BaseModelView):
""" """
return self.session.query(self.model) return self.session.query(self.model)
def get_count_query(self):
"""
Return a the count query for the model type
"""
return self.session.query( func.count('*') ).select_from(self.model)
def get_list(self, page, sort_column, sort_desc, search, filters, execute=True): def get_list(self, page, sort_column, sort_desc, search, filters, execute=True):
""" """
Return models from the database. Return models from the database.
...@@ -595,6 +601,7 @@ class ModelView(BaseModelView): ...@@ -595,6 +601,7 @@ class ModelView(BaseModelView):
joins = set() joins = set()
query = self.get_query() query = self.get_query()
count_query = self.get_count_query()
# Apply search criteria # Apply search criteria
if self._search_supported and search: if self._search_supported and search:
...@@ -602,6 +609,7 @@ class ModelView(BaseModelView): ...@@ -602,6 +609,7 @@ class ModelView(BaseModelView):
if self._search_joins: if self._search_joins:
for jn in self._search_joins.values(): for jn in self._search_joins.values():
query = query.join(jn) query = query.join(jn)
count_query = count_query.join(jn)
joins = set(self._search_joins.keys()) joins = set(self._search_joins.keys())
...@@ -615,6 +623,7 @@ class ModelView(BaseModelView): ...@@ -615,6 +623,7 @@ class ModelView(BaseModelView):
stmt = tools.parse_like_term(term) stmt = tools.parse_like_term(term)
filter_stmt = [c.ilike(stmt) for c in self._search_fields] filter_stmt = [c.ilike(stmt) for c in self._search_fields]
query = query.filter(or_(*filter_stmt)) query = query.filter(or_(*filter_stmt))
count_query = count_query.filter(or_(*filter_stmt))
# Apply filters # Apply filters
if filters and self._filters: if filters and self._filters:
...@@ -629,13 +638,15 @@ class ModelView(BaseModelView): ...@@ -629,13 +638,15 @@ class ModelView(BaseModelView):
for table in join_tables: for table in join_tables:
if table.name not in joins: if table.name not in joins:
query = query.join(table) query = query.join(table)
count_query = count_query.join(table)
joins.add(table.name) joins.add(table.name)
# Apply filter # Apply filter
query = flt.apply(query, value) query = flt.apply(query, value)
count_query = flt.apply(count_query, value)
# Calculate number of rows # Calculate number of rows
count = query.count() count = count_query.scalar()
# Auto join # Auto join
for j in self._auto_joins: for j in self._auto_joins:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment