gpt4 book ai didi

python - 如何使用 Pony ORM 存储 Python 枚举?

转载 作者:太空狗 更新时间:2023-10-29 17:18:56 27 4
gpt4 key购买 nike

假设我在这里有这个简单的小 Pony ORM 映射。内置 Enum 类是 Python 3.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 值,并在 StateTable 类中提供一个 getter 将值再次转换为 Enum。但这是乏味且容易出错的。我也可以只使用另一个 ORM。如果这个问题变得太令人头疼,也许我会的。但如果可以的话,我宁愿坚持使用 Pony。

我更愿意创建一个数据库转换器来存储枚举,就像错误消息所暗示的那样。有谁知道如何做到这一点?

更新:感谢 Ethan 的帮助,我想出了以下解决方案。

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))

最佳答案

Excerpt from some random mailing list :

2.2. CONVERTER METHODS

Each converter class should define the following methods:

class MySpecificConverter(Converter):

def init(self, kwargs):
# Override this method to process additional positional
# and keyword arguments of the attribute

if self.attr is not None:
# self.attr.args can be analyzed here
self.args = self.attr.args

self.my_optional_argument = kwargs.pop("kwarg_name")
# You should take all valid options from this kwargs
# What is left in is regarded as unrecognized option

def validate(self, val):
# convert value to the necessary type (e.g. from string)
# validate all necessary constraints (e.g. min/max bounds)
return val

def py2sql(self, val):
# prepare the value (if necessary) to storing in the database
return val

def sql2py(self, value):
# convert value (if necessary) after the reading from the db
return val

def sql_type(self):
# generate corresponding SQL type, based on attribute options
return "SOME_SQL_TYPE_DEFINITION"

You can study the code of the existing converters to see how these methods are implemented.

关于python - 如何使用 Pony ORM 存储 Python 枚举?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31395663/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com