How can I store a Python Enum using Pony ORM? -
say i've got simple little pony orm mapping here. built-in enum class new of python 3.4, , backported 2.7.
from enum import enum 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)
when run program, error thrown.
typeerror: no database converter found type <enum 'state'>
this happens because pony doesn't support mapping enum type. of course, workaround here store enum value, , provide getter in class statetable convert value enum once again. tedious , error prone. can use orm. maybe if issue becomes of headache. rather stick pony if can.
i rather create database converter store enum, error message hinting at. know how this?
update: ethan's help, have come following solution.
from enum import enum pony.orm import database, required, db_session 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 enum. got {}'.format(type(val))) return val def py2sql(self, val): return val.name def sql2py(self, value): # enum type can used, py_type ensures correct 1 used create enum instance return self.py_type[value] if __name__ == '__main__': db = database('sqlite', ':memory:', create_db=true) # register type converter database db.provider.converter_classes.append((enum, enumconverter)) class statetable(db.entity): state = required(state) db.generate_mapping(create_tables=true) db_session: s = statetable(state=state.ready) print('got {} db'.format(s.state))
2.2. converter methods
each converter class should define following methods:
class myspecificconverter(converter): def init(self, kwargs): # override method process additional positional # , keyword arguments of attribute if self.attr not none: # self.attr.args can analyzed here self.args = self.attr.args self.my_optional_argument = kwargs.pop("kwarg_name") # should take valid options kwargs # left in regarded unrecognized option def validate(self, val): # convert value necessary type (e.g. string) # validate necessary constraints (e.g. min/max bounds) return val def py2sql(self, val): # prepare value (if necessary) storing in database return val def sql2py(self, value): # convert value (if necessary) after reading db return val def sql_type(self): # generate corresponding sql type, based on attribute options return "some_sql_type_definition"
you can study code of existing converters see how these methods implemented.
Comments
Post a Comment