SQLalchemy give me the following warning when I use a Numeric column with an SQLite database engine.
SAWarning: Dialect sqlite+pysqlite does not>
Here is a solution inspired by both @van and @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
Like @Jinghui Niu mentioned, when decimal is stored as strings in sqlite, some query won't always function as expected, such as session.query(T).filter(T.value > 100), or things like sqlalchemy.sql.expression.func.min, or even order_by, because SQL compares strings (e.g. "9.2" > "19.2" in strings) instead of numerical values as we expected in these cases.