Pour obtenir une méthode as_dict
sur toutes mes classes je une classe Mixin
qui utilise les techniques décrites par 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
Et puis l'utiliser comme ceci dans vos classes
class MyClass(BaseMixin, Base):
pass
De cette façon, vous pouvez invoquer ce qui suit sur une instance de MyClass
.
> myclass = MyClass()
> myclass.as_dict()
Espérons que cela aide.
J'ai joué arround avec un peu plus loin, en fait je besoin de rendre mes instances comme dict
que la forme d'un HAL object avec ses liens vers des objets connexes. J'ai donc ajouté cette petite magie ici, qui va explorer toutes les propriétés de la classe comme ci-dessus, à la différence que je vais explorer plus en profondeur les propriétés Relaionship
et générer links
automatiquement.
S'il vous plaît noter que cela ne fonctionne que pour les relations ont une clé primaire unique
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
Notez que '__table__.columns' vous donnera les noms de champs SQL, pas les noms d'attributs que vous avez utilisés dans vos définitions ORM (si les deux sont différents). –
Puis-je recommander de changer ''sa_ '! = K [: 4]' à 'pas k.startswith (' _ sa _ ')'? –
Pas besoin de boucler avec inspecter: 'inspecter (JobStatus) .columns.keys()' – kirpit