考虑此代码(并使用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())
我可以使用:
轻松地对Arrete
类中定义的列的列类型进行内省
Arrete.__table__.c['date_arrete'].type
但如果我想通过Arrete
类访问Document
类中定义的列,则无效。 (如果我尝试访问c['date']
,则为KeyError。)
有没有办法获取列类型,无论列是在最终类中还是在其父类中定义的?
答案 0 :(得分:23)
ORM允许您在继承模式中定义类,这些模式对应于两个表的JOIN。这个结构是完整的服务,也可以用来找出基本的东西,比如列上的属性类型,非常直接:
type = Arrete.date.property.columns[0].type
请注意,这与通过__bases__
进行跋涉的方法基本相同,除非您让Python的普通类机制完成工作。
答案 1 :(得分:4)
您可以探索基类......
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')
答案 2 :(得分:0)
您需要abstract special directive或mixin pattern。
对于mixin,您可以使用以下内容:
class MyMixin(object):
__tablename__ = 'document'
__table_args__ = {
'schema': 'app'
}
id = Column(types.Integer, primary_key=True)
nom = Column(types.Unicode(256), nullable=False)
date = Column(types.Date())
class Arrete(MyMixin, Base):
__tablename__ = 'arrete'
__mapper_args__ = {'polymorphic_identity': 'arrete'}
foreign_id = Column(types.Integer, ForeignKey('app.document.id'), primary_key=True)
numero_arrete = Column(types.Integer)
date_arrete = Column(types.Date())
class Document(MyMixin, Base):
__tablename__ = 'Document'
type_document = Column(types.Enum('arrete', 'photographie',
name='TYPES_DOCUMENT_ENUM'))
__mapper_args__ = {'polymorphic_on': type_document}
共享内容包含在子类中的mixin和非共享内容中。