Para obtener un as_dict
método en todas mis clases, utilicé una Mixin
clase 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 úsalo así en tus clases.
class MyClass(BaseMixin, Base):
pass
De esa forma, puede invocar lo siguiente en una instancia de MyClass
.
> myclass = MyClass()
> myclass.as_dict()
Espero que esto ayude.
He jugado un poco más con esto, en realidad necesitaba renderizar mis instancias dict
como la forma de un objeto HAL con sus enlaces a objetos relacionados. Así que agregué esta pequeña magia aquí abajo, que rastreará todas las propiedades de la clase igual que la anterior, con la diferencia de que rastrearé más profundamente en las Relaionship
propiedades y generaré links
para estas automáticamente.
Tenga en cuenta que esto solo funcionará para las relaciones que tengan una única clave principal
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
__table__.columns
le dará los nombres de los campos SQL, no los nombres de los atributos que ha utilizado en sus definiciones ORM (si los dos difieren).