我在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_
?
答案 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)
我希望它对您有用。