SQLAlchemy内省具有继承的列类型

ton*_*nio 13 python inheritance sqlalchemy introspection

考虑此代码(并使用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())
Run Code Online (Sandbox Code Playgroud)

我可以很容易地对Arrete类中定义的列的列类型进行内省:

Arrete.__table__.c['date_arrete'].type
Run Code Online (Sandbox Code Playgroud)

但是,如果我想通过Arrete类访问类中定义的列,则这不起作用Document.(如果我尝试访问,则为KeyError c['date']).

有没有办法获得列类型,无论列是在最终类中还是在其父类中定义的?

zzz*_*eek 25

ORM允许您在继承模式中定义类,这些模式对应于两个表的JOIN.这个结构是完整的服务,也可以用来找出基本的东西,比如列上的属性类型,非常直接:

type = Arrete.date.property.columns[0].type
Run Code Online (Sandbox Code Playgroud)

请注意,这与跋涉的方法基本相同__bases__,除了你让Python的普通类机制完成工作.

  • @zzzeek “columns” 属性是列表有什么原因吗?是否存在第一个实例可能不正确的情况? (2认同)

gur*_*lex 6

您可以探索基类...

def find_type(class_, colname):
    if hasattr(class_, '__table__') and colname in class_.__table__.c:
        return class_.__table__.c[colname].type
    for base in class_.__bases__:
        return find_type(base, colname)
    raise NameError(colname)

print find_type(Arrete, 'date_arrete')
print find_type(Arrete, 'date')
Run Code Online (Sandbox Code Playgroud)