我怎样才能使用" class"作为Python / SQLAlchemy中的枚举值?

时间:2017-02-20 11:34:08

标签: python enums sqlalchemy

我在SQLAlchemy中有一个模型,其中一列是枚举。为了尽可能接近vanilla SQLAlchemy和Python3 stdlib,我已经针对stdlib的enum.Enum类定义了枚举,然后使用sqlalchemy.Enum将其提供给SQLAlchemy。 class(在SQLAlchemy文档中的某处推荐。)

class TaxonRank(enum.Enum):

    domain = "domain"
    kingdom = "kingdom"
    phylum = "phylum"
    class_ = "class"
    order = "order"
    family = "family"
    genus = "genus"
    species = "species"

在模型中:

rank = sqlalchemy.Column(sqlalchemy.Enum(TaxonRank), name = "rank", nullable = False)

这很有效,除了强迫我使用class_而不是class作为其中一个枚举值(当然是为了避免与Python关键字冲突;它是非法的语法尝试访问TaxonRank.class。)

我真的不介意使用class_,但我遇到的问题是class_是最终存储在数据库中的值。反过来,这会导致我的CRUD API出现问题,其中我允许用户执行类似"过滤排名以ss结尾的排名。"当然,这并不匹配任何东西,因为该值实际上以ss_结束!

对于记录显示,我一直在进行一些hacky逐个案例的翻译,以便始终向用户class显示class_。但是,在排序和过滤方面做类似的事情更棘手,因为我在SQL级别执行这两项操作。

所以我的问题是:围绕这种轻微的烦恼是否有好的方法?我并不真正关心在我的Python中访问TaxonRank.class_,但也许有一种方法可以将stdlib的enum.Enum子类化为强制{{1}的字符串表示形式属性(以及实际存储在数据库中的值)到期望的class_

2 个答案:

答案 0 :(得分:1)

感谢Sergey Shubin向我指出了另一种定义enum.Enum的形式。

TaxonRank = enum.Enum("TaxonRank", [
    ("domain", "domain"),
    ("kingdom", "kingdom"),
    ("phylum", "phylum"),
    ("class", "class"),
    ("order", "order"),
    ("family", "family"),
    ("genus", "genus"),
    ("species", "species")
])

答案 1 :(得分:0)

我一直在研究俄语和英语数据库的界面。我正在使用postgresql,但它可能适用于任何品牌X枚举。这是解决方案:

在mymodel.py中:

from sqlalchemy.dialects.postgresql import ENUM
from .meta import Base
from enum import Enum

class NounVar(Enum):
    abstract = 1
    proper = 2
    concrete = 3
    collective = 4,
    compound = 5

class Nouns(Base):
    __tablename__ = 'nouns'
    id = Column(Integer, primary_key=True)
    name = Column(Text) 
    runame = Column(Text)
    variety = Column("variety", ENUM(NounVar, name='variety_enum'))

然后再添加default.py:

from .models.mymodel import Nouns

class somecontainer():
    def somecallable():
        page = Nouns(
            name="word", 
            runame="слово",
            variety=NounVar().concrete))
        self.request.dbsession.add(page)

我希望它对您有用。