dbengine.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import records
  2. import re
  3. from babel.numbers import parse_decimal, NumberFormatError
  4. schema_re = re.compile(r'\((.+)\)')
  5. num_re = re.compile(r'[-+]?\d*\.\d+|\d+')
  6. agg_ops = ['', 'MAX', 'MIN', 'COUNT', 'SUM', 'AVG']
  7. cond_ops = ['=', '>', '<', 'OP']
  8. class DBEngine:
  9. def __init__(self, fdb):
  10. #fdb = 'data/test.db'
  11. self.db = records.Database('sqlite:///{}'.format(fdb))
  12. def execute_query(self, table_id, query, *args, **kwargs):
  13. return self.execute(table_id, query.sel_index, query.agg_index, query.conditions, *args, **kwargs)
  14. def execute(self, table_id, select_index, aggregation_index, conditions, lower=True):
  15. if not table_id.startswith('table'):
  16. table_id = 'table_{}'.format(table_id.replace('-', '_'))
  17. table_info = self.db.query('SELECT sql from sqlite_master WHERE tbl_name = :name', name=table_id).all()[0].sql.replace('\n','')
  18. schema_str = schema_re.findall(table_info)[0]
  19. schema = {}
  20. for tup in schema_str.split(', '):
  21. c, t = tup.split()
  22. schema[c] = t
  23. select = 'col{}'.format(select_index)
  24. agg = agg_ops[aggregation_index]
  25. if agg:
  26. select = '{}({})'.format(agg, select)
  27. where_clause = []
  28. where_map = {}
  29. for col_index, op, val in conditions:
  30. if lower and (isinstance(val, str) or isinstance(val, unicode)):
  31. val = val.lower()
  32. if schema['col{}'.format(col_index)] == 'real' and not isinstance(val, (int, float)):
  33. try:
  34. val = float(parse_decimal(val))
  35. except NumberFormatError as e:
  36. val = float(num_re.findall(val)[0])
  37. where_clause.append('col{} {} :col{}'.format(col_index, cond_ops[op], col_index))
  38. where_map['col{}'.format(col_index)] = val
  39. where_str = ''
  40. if where_clause:
  41. where_str = 'WHERE ' + ' AND '.join(where_clause)
  42. query = 'SELECT {} AS result FROM {} {}'.format(select, table_id, where_str)
  43. #print query
  44. out = self.db.query(query, **where_map)
  45. return [o.result for o in out]