diff --git a/trytond/backend/sqlite/database.py b/trytond/backend/sqlite/database.py index 7fb5a50064..6d1c5a108d 100644 --- a/trytond/backend/sqlite/database.py +++ b/trytond/backend/sqlite/database.py @@ -179,7 +179,8 @@ class Database(DatabaseInterface): raise IOError('Database "%s" doesn\'t exist!' % db_filename) if self._conn is not None: return self - self._conn = sqlite.connect(path, detect_types=sqlite.PARSE_DECLTYPES) + self._conn = sqlite.connect(path, + detect_types=sqlite.PARSE_DECLTYPES | sqlite.PARSE_COLNAMES) self._conn.create_function('extract', 2, SQLiteExtract.extract) self._conn.create_function('date_trunc', 2, date_trunc) self._conn.create_function('split_part', 3, split_part) diff --git a/trytond/model/fields/numeric.py b/trytond/model/fields/numeric.py index 3a0fcfa0df..ce9abdc58b 100644 --- a/trytond/model/fields/numeric.py +++ b/trytond/model/fields/numeric.py @@ -1,13 +1,20 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. from decimal import Decimal -from sql import Query, Expression, Cast, Literal, Select, CombiningQuery +from sql import Query, Expression, Cast, Literal, Select, CombiningQuery, As from ... import backend from .field import SQLType from .float import Float +class SQLite_Cast(Cast): + + def as_(self, output_name): + # Use PARSE_COLNAMES instead of CAST for final column + return As(self.expression, '%s [NUMERIC]' % output_name) + + class Numeric(Float): ''' Define a numeric field (``decimal``). @@ -36,7 +43,7 @@ class Numeric(Float): db_type = backend.name() if db_type == 'sqlite': # Must be casted as Decimal is stored as bytes - column = Cast(column, self.sql_type().base) + column = SQLite_Cast(column, self.sql_type().base) return column def _domain_value(self, operator, value): diff --git a/trytond/model/modelsql.py b/trytond/model/modelsql.py index 1cf63c4e99..01c81178f6 100644 --- a/trytond/model/modelsql.py +++ b/trytond/model/modelsql.py @@ -567,8 +567,9 @@ class ModelSQL(ModelStorage): columns = [] for f in fields_names + fields_related.keys() + datetime_fields: - if (f in cls._fields and not hasattr(cls._fields[f], 'set')): - columns.append(Column(table, f).as_(f)) + field = cls._fields.get(f) + if field and not hasattr(field, 'set'): + columns.append(field.sql_column(table).as_(f)) elif f == '_timestamp' and not table_query: sql_type = fields.Char('timestamp').sql_type().base columns.append(Extract('EPOCH', @@ -609,7 +610,8 @@ class ModelSQL(ModelStorage): result = [{'id': x} for x in ids] for column in columns: - field = column.output_name + # Split the output name to remove SQLite type detection + field = column.output_name.split()[0] if field == '_timestamp': continue if (getattr(cls._fields[field], 'translate', False) @@ -873,7 +875,7 @@ class ModelSQL(ModelStorage): and field.left and field.right): tree_ids[fname] = [] for sub_ids in grouped_slice(ids): - where = reduce_ids(Column(table, fname), sub_ids) + where = reduce_ids(field.sql_column(table), sub_ids) cursor.execute(*table.select(table.id, where=where)) tree_ids[fname] += [x[0] for x in cursor.fetchall()] @@ -1035,7 +1037,7 @@ class ModelSQL(ModelStorage): main_table.create_date).as_('_datetime')) columns.append(Column(main_table, '__id')) if not query: - columns += [Column(main_table, n).as_(n) + columns += [f.sql_column(main_table).as_(n) for n, f in cls._fields.iteritems() if not hasattr(f, 'get') and n != 'id'