假设我这里有一个简单的小马ORM地图。内置Enum类是Python3.4中的新版本,支持2.7。
from enum import Enum
from pony.orm import Database, Required
class State(Enum):
ready = 0
running = 1
errored = 2
if __name__ == '__main__':
db = Database('sqlite', ':memory:', create_db=True)
class StateTable(db.Entity):
state = Required(State)
db.generate_mapping(create_tables=True)当我运行程序时,会抛出一个错误。
TypeError: No database converter found for type <enum 'State'>这是因为Pony不支持映射枚举类型。当然,这里的解决方法是只存储Enum值,并在Class StateTable中提供一个getter来再次将值转换为Enum。但这是乏味和容易出错的。我也可以再用一个ORM。如果这个问题让我头疼的话,也许我会的。但如果可以的话,我宁愿和小马呆在一起。
我更愿意创建一个数据库转换器来存储枚举,就像错误消息所暗示的那样。有人知道怎么做吗?
更新:感谢伊森的帮助,我提出了以下解决方案。
from enum import Enum
from pony.orm import Database, Required, db_session
from pony.orm.dbapiprovider import StrConverter
class State(Enum):
ready = 0
running = 1
errored = 2
class EnumConverter(StrConverter):
def validate(self, val):
if not isinstance(val, Enum):
raise ValueError('Must be an Enum. Got {}'.format(type(val)))
return val
def py2sql(self, val):
return val.name
def sql2py(self, value):
# Any enum type can be used, so py_type ensures the correct one is used to create the enum instance
return self.py_type[value]
if __name__ == '__main__':
db = Database('sqlite', ':memory:', create_db=True)
# Register the type converter with the database
db.provider.converter_classes.append((Enum, EnumConverter))
class StateTable(db.Entity):
state = Required(State)
db.generate_mapping(create_tables=True)
with db_session:
s = StateTable(state=State.ready)
print('Got {} from db'.format(s.state))发布于 2015-07-14 01:34:40
2.2。换流法 每个转换器类都应该定义以下方法: 类MySpecificConverter(转换器):def init(self,):#重写此方法以处理属性的附加位置#和关键字参数(如果self.attr不是None):# self.attr.args可以在这里分析self.args = self.attr.args self.my_optional_argument = kwargs.pop("kwarg_name") #您应该从这个kwargs中获取所有有效的选项#剩余的选项被认为是不可识别的选项def验证(self,#将值转换为必需的类型(例如,从字符串)#验证所有必要的约束(例如min/max界限),返回value py2sql(self,val):#准备值(如果必要的话)以存储在数据库中的value sql2py(self,值):#转换值(如果必要的话),在从db返回value sql_type(Self)读取之后:#生成相应的SQL类型,根据属性选项返回"SOME_SQL_TYPE_DEFINITION“ 您可以研究现有转换器的代码,以了解这些方法是如何实现的。
https://stackoverflow.com/questions/31395663
复制相似问题