Refs #28459 -- Improved performance of loading DecimalField on SQLite.
This commit is contained in:
parent
4c599ece57
commit
d0f569b350
|
@ -39,7 +39,6 @@ Database.register_converter("date", decoder(parse_date))
|
||||||
Database.register_converter("datetime", decoder(parse_datetime))
|
Database.register_converter("datetime", decoder(parse_datetime))
|
||||||
Database.register_converter("timestamp", decoder(parse_datetime))
|
Database.register_converter("timestamp", decoder(parse_datetime))
|
||||||
Database.register_converter("TIMESTAMP", decoder(parse_datetime))
|
Database.register_converter("TIMESTAMP", decoder(parse_datetime))
|
||||||
Database.register_converter("decimal", decoder(decimal.Decimal))
|
|
||||||
|
|
||||||
Database.register_adapter(decimal.Decimal, backend_utils.rev_typecast_decimal)
|
Database.register_adapter(decimal.Decimal, backend_utils.rev_typecast_decimal)
|
||||||
|
|
||||||
|
|
|
@ -214,7 +214,7 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||||
elif internal_type == 'TimeField':
|
elif internal_type == 'TimeField':
|
||||||
converters.append(self.convert_timefield_value)
|
converters.append(self.convert_timefield_value)
|
||||||
elif internal_type == 'DecimalField':
|
elif internal_type == 'DecimalField':
|
||||||
converters.append(self.convert_decimalfield_value)
|
converters.append(self.get_decimalfield_converter(expression))
|
||||||
elif internal_type == 'UUIDField':
|
elif internal_type == 'UUIDField':
|
||||||
converters.append(self.convert_uuidfield_value)
|
converters.append(self.convert_uuidfield_value)
|
||||||
elif internal_type in ('NullBooleanField', 'BooleanField'):
|
elif internal_type in ('NullBooleanField', 'BooleanField'):
|
||||||
|
@ -241,15 +241,21 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||||
value = parse_time(value)
|
value = parse_time(value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def convert_decimalfield_value(self, value, expression, connection):
|
def get_decimalfield_converter(self, expression):
|
||||||
if value is not None:
|
# SQLite stores only 15 significant digits. Digits coming from
|
||||||
if not isinstance(expression, Col):
|
# float inaccuracy must be removed.
|
||||||
# SQLite stores only 15 significant digits. Digits coming from
|
create_decimal = decimal.Context(prec=15).create_decimal_from_float
|
||||||
# float inaccuracy must be removed.
|
if isinstance(expression, Col):
|
||||||
return decimal.Context(prec=15).create_decimal_from_float(value)
|
quantize_value = decimal.Decimal(1).scaleb(-expression.output_field.decimal_places)
|
||||||
value = expression.output_field.format_number(value)
|
|
||||||
return decimal.Decimal(value)
|
def converter(value, expression, connection):
|
||||||
return value
|
if value is not None:
|
||||||
|
return create_decimal(value).quantize(quantize_value, context=expression.output_field.context)
|
||||||
|
else:
|
||||||
|
def converter(value, expression, connection):
|
||||||
|
if value is not None:
|
||||||
|
return create_decimal(value)
|
||||||
|
return converter
|
||||||
|
|
||||||
def convert_uuidfield_value(self, value, expression, connection):
|
def convert_uuidfield_value(self, value, expression, connection):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
|
|
|
@ -1560,20 +1560,6 @@ class DecimalField(Field):
|
||||||
params={'value': value},
|
params={'value': value},
|
||||||
)
|
)
|
||||||
|
|
||||||
def format_number(self, value):
|
|
||||||
"""
|
|
||||||
Format a number into a string with the requisite number of digits and
|
|
||||||
decimal places.
|
|
||||||
"""
|
|
||||||
# Method moved to django.db.backends.utils.
|
|
||||||
#
|
|
||||||
# It is preserved because it is used by the oracle backend
|
|
||||||
# (django.db.backends.oracle.query), and also for
|
|
||||||
# backwards-compatibility with any external code which may have used
|
|
||||||
# this method.
|
|
||||||
from django.db.backends import utils
|
|
||||||
return utils.format_number(value, self.max_digits, self.decimal_places)
|
|
||||||
|
|
||||||
def get_db_prep_save(self, value, connection):
|
def get_db_prep_save(self, value, connection):
|
||||||
return connection.ops.adapt_decimalfield_value(self.to_python(value), self.max_digits, self.decimal_places)
|
return connection.ops.adapt_decimalfield_value(self.to_python(value), self.max_digits, self.decimal_places)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue