这是一个受@van 和@JosefAssad 启发的解决方案。
class SqliteDecimal(TypeDecorator):
# This TypeDecorator use Sqlalchemy Integer as impl. It converts Decimals
# from Python to Integers which is later stored in Sqlite database.
impl = Integer
def __init__(self, scale):
# It takes a 'scale' parameter, which specifies the number of digits
# to the right of the decimal point of the number in the column.
TypeDecorator.__init__(self)
self.scale = scale
self.multiplier_int = 10 ** self.scale
def process_bind_param(self, value, dialect):
# e.g. value = Column(SqliteDecimal(2)) means a value such as
# Decimal('12.34') will be converted to 1234 in Sqlite
if value is not None:
value = int(Decimal(value) * self.multiplier_int)
return value
def process_result_value(self, value, dialect):
# e.g. Integer 1234 in Sqlite will be converted to Decimal('12.34'),
# when query takes place.
if value is not None:
value = Decimal(value) / self.multiplier_int
return value
就像@Jinghui Niu 提到的,当十进制作为字符串存储在sqlite 中时,某些查询不会总是按预期运行,例如session.query(T).filter(T.value > 100) 或sqlalchemy.sql 之类的东西。 expression.func.min,甚至 order_by,因为 SQL 比较的是字符串(例如字符串中的“9.2”>“19.2”),而不是我们在这些情况下所期望的数值。