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("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)
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ class DatabaseOperations(BaseDatabaseOperations):
|
|||
elif internal_type == 'TimeField':
|
||||
converters.append(self.convert_timefield_value)
|
||||
elif internal_type == 'DecimalField':
|
||||
converters.append(self.convert_decimalfield_value)
|
||||
converters.append(self.get_decimalfield_converter(expression))
|
||||
elif internal_type == 'UUIDField':
|
||||
converters.append(self.convert_uuidfield_value)
|
||||
elif internal_type in ('NullBooleanField', 'BooleanField'):
|
||||
|
@ -241,15 +241,21 @@ class DatabaseOperations(BaseDatabaseOperations):
|
|||
value = parse_time(value)
|
||||
return value
|
||||
|
||||
def convert_decimalfield_value(self, value, expression, connection):
|
||||
if value is not None:
|
||||
if not isinstance(expression, Col):
|
||||
# SQLite stores only 15 significant digits. Digits coming from
|
||||
# float inaccuracy must be removed.
|
||||
return decimal.Context(prec=15).create_decimal_from_float(value)
|
||||
value = expression.output_field.format_number(value)
|
||||
return decimal.Decimal(value)
|
||||
return value
|
||||
def get_decimalfield_converter(self, expression):
|
||||
# SQLite stores only 15 significant digits. Digits coming from
|
||||
# float inaccuracy must be removed.
|
||||
create_decimal = decimal.Context(prec=15).create_decimal_from_float
|
||||
if isinstance(expression, Col):
|
||||
quantize_value = decimal.Decimal(1).scaleb(-expression.output_field.decimal_places)
|
||||
|
||||
def converter(value, expression, connection):
|
||||
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):
|
||||
if value is not None:
|
||||
|
|
|
@ -1560,20 +1560,6 @@ class DecimalField(Field):
|
|||
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):
|
||||
return connection.ops.adapt_decimalfield_value(self.to_python(value), self.max_digits, self.decimal_places)
|
||||
|
||||
|
|
Loading…
Reference in New Issue