Sag, ich habe dieses einfache kleine Pony ORM Mapping hier. Die integrierte Enum-Klasse ist ab Python 3.4 neu und wurde auf 2.7 zurückportiert.Wie kann ich ein Python Enum mit Pony ORM speichern?
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)
Wenn ich das Programm ausführen, wird ein Fehler ausgelöst.
TypeError: No database converter found for type <enum 'State'>
Dies passiert, weil Pony die Zuordnung des Aufzählungstyps nicht unterstützt. Natürlich besteht die Problemumgehung darin, den Enum-Wert nur zu speichern und einen Getter in der Klasse StateTable bereitzustellen, um den Wert erneut in Enum zu konvertieren. Aber das ist mühsam und fehleranfällig. Ich kann auch einfach ein anderes ORM verwenden. Vielleicht werde ich es tun, wenn dieses Problem zu viele Kopfschmerzen verursacht. Aber ich würde lieber bei Pony bleiben, wenn ich kann.
Ich würde viel lieber einen Datenbankkonverter erstellen, um die enum zu speichern, wie die Fehlermeldung darauf hinweist. Weiß jemand, wie man das macht?
UPDATE: Dank Ethans Hilfe, habe ich die folgende Lösung gefunden.
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))
Danke! Ich hatte dieses Posting schon einmal gesehen, aber ich dachte, es ginge darum, SQL-Typen hinzuzufügen, und nicht Python-Typen. Ich habe meine Frage aktualisiert, um eine Lösung zu zeigen, die mir einfällt. – zalpha314