Cuando los atributos de la clase ORM sqlalchemy son diferentes de las columnas de la base de datos, ¿cómo obtener una lista de los atributos de la clase ORM?

Digamos que quiere iterar sobre los atributos ORM de una clase ORM en sqlalchemy. Por lo tanto, desea una lista de los atributos ORM. ¿Cómo se obtiene esa lista?

Si la clase ORM no cambia el nombre de los atributos y, por lo tanto, los atributos ORM coinciden con las columnas de la base de datos, entonces puede usar la solución desde: https://stackoverflow.com/a/24748320/1023033 (por cierto, también hay una La función (privada) _orm_columns () en el archivo de código fuente /lib/sqlalchemy/orm/base.py que parece proporcionar esta funcionalidad)

Pero si la clase ORM de python tiene nombres diferentes a las columnas de la base de datos (por ejemplo, en estos 3 atributos ORM):

>>> class User(Base): ... __tablename__ = 'users' ... ... id = Column('pkey', Integer, primary_key=True) ... name = Column('user_name', String) ... fullname = Column('human_name', String) 

entonces ese método no funciona. Entonces, ¿cómo se obtiene la versión de python de los atributos ORM?

Esto ya está implementado utilizando el sistema de inspección :

 from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import inspect Base = declarative_base() class A(Base): __tablename__ = 'a' id = Column(Integer, primary_key=True) x = Column(Integer) y = Column(Integer) print inspect(A).c print inspect(A).cx print inspect(A).column_attrs print inspect(A).column_attrs.x print inspect(A).column_attrs.x.expression 

http://docs.sqlalchemy.org/en/latest/core/inspection.html

http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html#sqlalchemy.orm.mapper.Mapper.all_orm_descriptors

http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html#sqlalchemy.orm.mapper.Mapper.columns

http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html#sqlalchemy.orm.mapper.Mapper.column_attrs

http://docs.sqlalchemy.org/en/latest/orm/mapping_api.html#sqlalchemy.orm.mapper.Mapper.c

Definí una clase mixta para boost

 Base = declarative_base() 

con la clase mixin definida como:

 import inspect import sqlalchemy as sqla class orm_mixin_class(object): """Additional functionality wanted in orm classes (that inherit from Base).""" @classmethod def orm_class_info(cls): """ Get info about the orm class (as opposed to the database table it is mapped to). Returns: list of dict where each dict describes a orm class attribute. Keys: s_class_attribute_name """ o_leaf_level_class = cls # this turns out the be the leaf class instead of this mixin class l_orm_attribute_pairs = inspect.getmembers(o_leaf_level_class) l_orm_class_info_dicts = [] for (s_class_attribute_name, o_attr_type) in l_orm_attribute_pairs: d_attr_info = {} b_orm_attribute = False try: o_inspect = sqla.inspection.inspect(o_attr_type) if isinstance(o_inspect, sqla.orm.attributes.QueryableAttribute): b_orm_attribute = True d_attr_info['s_class_attribute_name'] = s_class_attribute_name except: pass if b_orm_attribute: # only orm attributes have an entry in the output list l_orm_class_info_dicts.append(d_attr_info) return(l_orm_class_info_dicts) 

por lo que la lista de atributos ORM se puede obtener fácilmente de una llamada de método.

La statement de clase ORM es ahora:

 class User(Base, orm_mixin_class):