Dire che ho questa semplice piccola mappatura Pony ORM qui. La classe Enum incorporata è nuova a partire da Python 3.4 e backportata a 2.7.Come posso memorizzare un Python Enum usando Pony ORM?
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)
Quando si esegue il programma, viene generato un errore.
TypeError: No database converter found for type <enum 'State'>
Ciò accade perché Pony non supporta la mappatura del tipo enum. Ovviamente, la soluzione qui è solo per memorizzare il valore Enum e fornire un getter in Class StateTable per convertire nuovamente il valore in Enum. Ma questo è noioso e soggetto a errori. Posso anche solo usare un altro ORM. Forse lo farò se questo problema diventasse troppo mal di testa. Ma preferirei restare con Pony se posso.
Preferirei creare un convertitore di database per archiviare l'enumerazione, come suggerisce il messaggio di errore. Qualcuno sa come fare questo?
AGGIORNAMENTO: Grazie all'aiuto di Ethan, ho trovato la seguente soluzione.
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))
Grazie! Avevo visto quella pubblicazione prima, ma pensavo che si trattava di aggiungere tipi SQL e non di tipi python. Ho aggiornato la mia domanda per mostrare una soluzione che mi è venuta in mente. – zalpha314