Commit 6c1747f9 authored by LE GAC Renaud's avatar LE GAC Renaud
Browse files

Speed up BaseReport._do_data by limiting the database fields in the select.

parent 15dd1012
......@@ -9,7 +9,7 @@ import re
from datetime import date, timedelta
from gluon import current
from gluon.dal import Field, smart_query
from gluon.dal import Field, FieldVirtual, smart_query
from gluon.storage import Storage
from plugin_dbui import get_id, Store
from StringIO import StringIO
......@@ -72,25 +72,39 @@ def get_value(row, tablename, fieldname, keyname='', **kwargs):
@param keyname:
@return:
- C{row[tablename][fieldname]}
- C{row[tablename][fieldname]} or C{row[fieldname]}
when tablename and fieldname are defined
- C{row[tablename][fieldname][keyname]} for JSON type field
- C{kwargs[tablename]} when fieldname and keyname are not defined
- empty string
"""
# standard field
if fieldname and not keyname:
return row[tablename][fieldname]
undefined = ""
# JSON type database field containing a dict
if keyname and keyname in row[tablename][fieldname]:
return row[tablename][fieldname][keyname]
# when only tablename is defined have a look to the keyword value
if tablename in kwargs:
# force value
if tablename and (not fieldname) and (tablename in kwargs):
return kwargs[tablename]
# field is addressed in the row by tablename and by fieldname
if tablename in row:
value = row[tablename][fieldname]
# field is addressed in the row by its fieldname only
elif fieldname in row:
value = row[fieldname]
return ""
else:
return undefined
# deal with the keyname
# it has been design for JSON-type field containing a dictionary
if not keyname:
return value
elif keyname and keyname in value:
return value[keyname]
return undefined
def split_dbfield(value):
......@@ -181,7 +195,20 @@ class BaseReport(object):
selector = self.selector
convert = self._convert
query = selector.query
# limit the list of database fields to speed up processing:
# - keep those required by the user
# - remove virtual field
# - add standard fields require to compute virtual fields
dbfields = [db[el[0]][el[1]] for el in maps if el[1]]
dbfields = [el for el in dbfields if not isinstance(el, FieldVirtual)]
dbfields.extend([db.history.end_date,
db.history.percentage,
db.history.start_date,
db.people.birth_date])
# the year axis is on
# scan the database and compute virtual field on the year basis
if self._is_year(maps):
......@@ -190,18 +217,18 @@ class BaseReport(object):
for year in selector.get_years():
selector.set_year(year)
for row in selector.select(db.history):
for row in db(query(db.history)).select(*dbfields):
values = [get_value(row, *map, year=year) for map in maps]
values = [convert(value) for value in values]
data.append(values)
# standard scan
else:
for row in selector.select(db.history):
for row in db(query(db.history)).select(*dbfields):
values = [get_value(row, *map) for map in maps]
values = [convert(value) for value in values]
data.append(values)
return data
......
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