Para obtener un método as_dict
en todas mis clases he utilizado una clase Mixin
que utiliza las técnicas descritas por 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
y luego usarlo como este en sus clases
class MyClass(BaseMixin, Base):
pass
De este modo puede invocar la siguiente en una instancia de MyClass
.
> myclass = MyClass()
> myclass.as_dict()
Espero que esto ayude.
He jugado arround con esto un poco más lejos, lo que realmente se necesita para hacer mis casos como dict
como la forma de un HAL object con sus enlaces a objetos relacionados. Así que he agregado esta pequeña magia aquí, que se rastreará sobre todas las propiedades de la clase como la anterior, con la diferencia de que me arrastraré más profundamente en las propiedades Relaionship
y generaré links
automáticamente.
Tenga en cuenta que esto sólo funcionará para las relaciones tienen una única clave primaria
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
Tenga en cuenta que '__table__.columns' le dará los nombres de los campos de SQL, no los nombres de atributos que ha usado en sus definiciones de ORM (si los dos son diferentes). –
¿Podría recomendar cambiar ''_sa_'!! = K [: 4]' a 'no k.iniciar con ('_ sa _')'? –
No es necesario bucle con inspeccionar: 'inspeccionar (JobStatus) .columns.keys()' – kirpit