【问题标题】:How to query a table that has ENUM column and keep the ENUM type?如何查询具有 ENUM 列的表并保持 ENUM 类型?
【发布时间】:2021-11-22 11:02:44
【问题描述】:

我正在使用 SQLAlchemy ORM。

我在 SQL DB 中有一个表,其中有一个 id 列和一个名为 b 的列,它是枚举类型,可以取值 ('example_1', 'example_2')

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

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

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

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

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

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

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

【问题讨论】:

    标签: python sqlalchemy orm


    【解决方案1】:

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

    b = Column(Enum(BTypes).values_callable)
    

    给我:

    sqlalchemy.exc.CompileError:(在表'example',列'b'):无法为NullType()生成DDL;您是否忘记在此列上指定类型?

    关于NullType

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

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

    NullType 可以毫无问题地在 SQL 表达式调用中使用,它只是在表达式构造级别或绑定参数/结果处理级别没有任何行为。

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

    如何使用Enum.values_callable参数

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

    为了保留值而不是名称,可以使用Enum.values_callable 参数。此参数的值是用户提供的可调用对象,旨在与符合 PEP-435 的枚举类一起使用,并返回要保留的字符串值列表。对于使用字符串值的简单枚举,lambda x: [e.value for e in x] 之类的可调用对象就足够了。

    那就是:

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

    【讨论】:

      【解决方案2】:

      修改您的代码以查询表,如下所示以获取枚举:

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

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

      values_callable – 将传递符合 PEP-435 的枚举类型的可调用对象,然后应返回要保留的字符串值列表。这允许替代用法,例如使用枚举的字符串值而不是其名称持久化到数据库。

      【讨论】:

      • 谢谢,但这个答案不起作用。删除可调用的值会产生错误。原因是,没有可调用的值,sqlaclehmy 认为字符串值为'EXAMPLE_1''EXAMPLE_2',而sql 表没有这些值。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-21
      • 2013-09-15
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      相关资源
      最近更新 更多