SQLAlchemy introspect column type with inheritance

tonio picture tonio · Jul 24, 2012 · Viewed 12.4k times · Source

Considering this code (and using SQLAlchemy 0.7.7):

class Document(Base):
    __tablename__ = 'document'
    __table_args__ = {
        'schema': 'app'
    }

    id = Column(types.Integer, primary_key=True)
    nom = Column(types.Unicode(256), nullable=False)
    date = Column(types.Date())

    type_document = Column(types.Enum('arrete', 'photographie',
        name='TYPES_DOCUMENT_ENUM'))
    __mapper_args__ = {'polymorphic_on': type_document}

class Arrete(Document):
    __tablename__ = 'arrete'
    __table_args__ = {
        'schema': 'app'
    }
    __mapper_args__ = {'polymorphic_identity': 'arrete'}

    id = Column(types.Integer, ForeignKey('app.document.id'), primary_key=True)
    numero_arrete = Column(types.Integer)
    date_arrete = Column(types.Date())

I can easily introspect column type for column defined in Arrete class with:

Arrete.__table__.c['date_arrete'].type

But this doesn’t work if I want to access, through the Arrete class, a column defined in Document class. (KeyError if I try to access c['date']).

Is there a way to get column type, regardless if the column is defined in the final class or in one of its parent?

Answer

zzzeek picture zzzeek · Jul 24, 2012

The ORM has allowed you to define classes in an inheritance pattern that corresponds to a JOIN of two tables. This structure is full service, and can also be used to find out basic things like the types of attributes on columns, pretty much directly:

type = Arrete.date.property.columns[0].type

note that this is basically the same thing as the approach of trudging through __bases__, except you let Python's normal class mechanics do the work.