Как я должен обрабатывать десятичное значение в SQLalchemy & SQLite
SQLalchemy дает мне следующее предупреждение, когда я использую столбец Numeric с механизмом базы данных SQLite.
SAWarning: Dialect sqlite + pysqlite не поддерживает десятичные объекты изначально
Я пытаюсь найти лучший способ иметь pkgPrice = Column(Numeric(12,2))
в SQLalchemy при использовании SQLite.
Этот вопрос [1] Как преобразовать десятичное число Python в числовое число SQLite? показывает способ использования sqlite3.register_adapter(D, adapt_decimal)
, чтобы SQLite получал и возвращал Decimal, но сохранял строки, но я не знаю, как копаться в ядре SQLAlchemy, чтобы сделать это еще. Тип Декораторы выглядят как правильный подход, но я их еще не убеждаю.
Есть ли у кого-нибудь рецепт декодера типа SQLAlchemy, который будет иметь числовые или десятичные числа в модели SQLAlchemy, но хранить их как строки в SQLite?
Ответы
Ответ 1
from decimal import Decimal as D
import sqlalchemy.types as types
class SqliteNumeric(types.TypeDecorator):
impl = types.String
def load_dialect_impl(self, dialect):
return dialect.type_descriptor(types.VARCHAR(100))
def process_bind_param(self, value, dialect):
return str(value)
def process_result_value(self, value, dialect):
return D(value)
# can overwrite the imported type name
# @note: the TypeDecorator does not guarantie the scale and precision.
# you can do this with separate checks
Numeric = SqliteNumeric
class T(Base):
__tablename__ = 't'
id = Column(Integer, primary_key=True, nullable=False, unique=True)
value = Column(Numeric(12, 2), nullable=False)
#value = Column(SqliteNumeric(12, 2), nullable=False)
def __init__(self, value):
self.value = value
Ответ 2
Так как похоже, что вы используете десятичные значения для значений валюты, я бы предложил вам сделать безопасную вещь и сохранить значение валюты в ее наименьшем наименовании, например. 1610 центов вместо 16,10 долларов. Затем вы можете просто использовать тип столбца Integer.
Возможно, это не тот ответ, который вы ожидали, но он решает вашу проблему и обычно считается разумным дизайном.