Use Field.sql_column for SELECT queries in ModelSQL
By using sql_column, it increases the possibilities of customisation of fields. issue4369 review14711002
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user