SQLAlchemy:如何以不同于数据库的方式在 Python 中表示数据

SQLAlchemy: How to represent data in Python differently than in the database

在 (postgres) SQLAlchemy model/class 中,我有几列是 'price' 列。我已经读到对这种数据使用 numeric/money/float 类型不是一个好主意,所以我存储为 INT(便士)。

我已经为这些列创建了验证器,这些验证器会将输入值乘以 100,并在插入和更新时转换为 INT,这样就可以处理了。

如何反向操作?当我 select 此数据时,我想将这些值转换为浮点数,然后除以 100。我似乎无法找到合适的 sqlalchemy 事件侦听器来执行此操作。有正确的做法吗?

PS。作为奖励积分,我可能还想转换为字符串并添加一个“$”前缀,所以这个解决方案对我来说非常有用。

我不建议为此使用验证器。相反,我建议使用 TypeDecorator;请参阅 SQLAlchemy 文档中的 this discussion。您将为 Price 类型创建一个 TypeDecorator,它在绑定处理时乘以 100,在行处理时除法。 这是一个简单的示例,它处理我拥有的一些代码中的 uuid 类型:

from sqlalchemy.types import TypeDecorator, CHAR
import uuid


class GUID(TypeDecorator):
# Also see:
# http://docs.sqlalchemy.org/en/latest/core/custom_types.html#backend-agnostic-guid-type

impl = CHAR

    def process_bind_param(self, value, dialect):
        if value is None:
            return value
        else:
            if not isinstance(value, uuid.UUID):
                 return uuid.UUID(value).hex
            else:
                return value.hex

    def process_result_value(self, value, dialect):
        if value is None:
            return value
        else:
            return uuid.UUID(value)

除了 sqlite 之外,将 impl 设置为 char 是错误的,因为这不会设置声明的列的长度。 这应该可以让您了解如何组合价格类型。