Подтвердить что ты не робот

Как я должен обрабатывать десятичное значение в 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?

4b9b3361

Ответ 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.

Возможно, это не тот ответ, который вы ожидали, но он решает вашу проблему и обычно считается разумным дизайном.