问题
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?
回答1:
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.
回答2:
You can explore the base classes...
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')
回答3:
You need the abstract special directive or the mixin pattern.
For a mixin, you'd use something like this:
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}
Shared stuff goes in the mixin, non shared stuff in the sub classes.
来源:https://stackoverflow.com/questions/11632513/sqlalchemy-introspect-column-type-with-inheritance