per ottenere un metodo di as_dict
su tutti i miei corsi ho usato una classe Mixin
che utilizza le tecniche descritte da Ants Aasma.
class BaseMixin(object):
def as_dict(self):
result = {}
for prop in class_mapper(self.__class__).iterate_properties:
if isinstance(prop, ColumnProperty):
result[prop.key] = getattr(self, prop.key)
return result
e quindi utilizzarlo come questo nelle classi
class MyClass(BaseMixin, Base):
pass
In questo modo è possibile richiamare le seguenti su un'istanza di MyClass
.
> myclass = MyClass()
> myclass.as_dict()
Spero che questo aiuti.
Ho giocato arround con questo un po 'più lontano, in realtà ho bisogno di rendere le mie istanze come dict
come la forma di un HAL object con i suoi collegamenti a oggetti correlati. Così ho aggiunto questa piccola magia qui, che gattonerà su tutte le proprietà della classe come sopra, con la differenza che cercherò più in profondità nelle proprietà Relaionship
e genererò automaticamente links
.
prega di notare che questo funziona solo per le relazioni hanno un unico primario chiave
from sqlalchemy.orm import class_mapper, ColumnProperty
from functools import reduce
def deepgetattr(obj, attr):
"""Recurses through an attribute chain to get the ultimate value."""
return reduce(getattr, attr.split('.'), obj)
class BaseMixin(object):
def as_dict(self):
IgnoreInstrumented = (
InstrumentedList, InstrumentedDict, InstrumentedSet
)
result = {}
for prop in class_mapper(self.__class__).iterate_properties:
if isinstance(getattr(self, prop.key), IgnoreInstrumented):
# All reverse relations are assigned to each related instances
# we don't need to link these, so we skip
continue
if isinstance(prop, ColumnProperty):
# Add simple property to the dictionary with its value
result[prop.key] = getattr(self, prop.key)
if isinstance(prop, RelationshipProperty):
# Construct links relaions
if 'links' not in result:
result['links'] = {}
# Get value using nested class keys
value = (
deepgetattr(
self, prop.key + "." + prop.mapper.primary_key[0].key
)
)
result['links'][prop.key] = {}
result['links'][prop.key]['href'] = (
"/{}/{}".format(prop.key, value)
)
return result
Si noti che '__table__.columns' vi darà i nomi dei campi SQL, non i nomi degli attributi che avete usato nelle vostre definizioni ORM (se i due differiscono). –
Potrei raccomandare di cambiare ''_sa_'! = K [: 4]' a 'non k.startswith ('_ sa _')'? –
Non è necessario eseguire il ciclo con inspect: 'inspect (JobStatus) .columns.keys()' – kirpit