如何查询具有 ENUM 列的 table 并保持 ENUM 类型?

How to query a table that has ENUM column and keep the ENUM type?

我正在使用 SQLAlchemy ORM。

我在 SQL 数据库中有一个 table,它有一个 id 列,还有一个名为 b 的列,它是枚举类型,可以取值 ('example_1', 'example_2').

在 Python 中,我有一个 Enum class 这样的:

class BTypes(enum.Enum):
    EXAMPLE_1 = 'example_1'
    EXAMPLE_2 = 'example_2'

为了查询 table,我有一个这样的 ORM:

class Example(Base):
    __tablename__ = "example"
    id = Column(Integer, primary_key=True)
    b = Column(Enum(BTypes).values_callable)

当我执行 session.query(Example).all() 时,我返回的对象具有 b 属性的 str 类型。换句话说:

data = session.query(Example).all()
print(data[0].b)
# Outputs
# example_1

我希望属性 bExample 对象具有 enum 类型,而不是 str。实现此目标的最佳方法是什么?

修改您的代码以如下查询 table 以获取枚举:

   class Example(Base):
        __tablename__ = "example"
         id = Column(Integer, primary_key=True)
         b = Column(Enum(BTypes))

注意 values_callable 通常是 return 字符串值列表。 请查看 documentation 了解更多信息

values_callable – A callable which will be passed the PEP-435 compliant enumerated type, which should then return a list of string values to be persisted. This allows for alternate usages such as using the string value of an enum to be persisted to the database instead of its name.

Base.metadata.create_all(create_engine("sqlite://")) 与:

b = Column(Enum(BTypes).values_callable)

给我:

sqlalchemy.exc.CompileError: (in table 'example', column 'b'): Can't generate DDL for NullType(); did you forget to specify a type on this Column?

关于NullType

由于 Enum(BTypes).values_callableNone,SQLAlchemy 默认为 NullType

来自 https://docs.sqlalchemy.org/en/14/core/type_api.html#sqlalchemy.types.NullType:

The NullType can be used within SQL expression invocation without issue, it just has no behavior either at the expression construction level or at the bind-parameter/result processing level.

换句话说,当我们query时,它的值只是从数据库中按原样赋值。

如何使用Enum.values_callable参数

来自 https://docs.sqlalchemy.org/en/14/core/type_basics.html#sqlalchemy.types.Enum:

In order to persist the values and not the names, the Enum.values_callable parameter may be used. The value of this parameter is a user-supplied callable, which is intended to be used with a PEP-435-compliant enumerated class and returns a list of string values to be persisted. For a simple enumeration that uses string values, a callable such as lambda x: [e.value for e in x] is sufficient.

那就是:

b = Column(Enum(BTypes, values_callable=lambda x: [e.value for e in x]))