SQLAlchemyinheritance
我对sqlalchemy下的inheritance有点困惑,我甚至不知道我应该在这里使用什么types的inheritance(单表,连接表,具体)。 我有一个基类,其中包含一些在子类中共享的信息,以及一些完全独立的数据。 有时候,我会需要所有类的数据,有时只需要来自子类的数据。 这是一个例子:
class Building: def __init__(self, x, y): self.x = x self.y = y class Commercial(Building): def __init__(self, x, y, business): Building.__init__(self, x, y) self.business = business class Residential(Building): def __init__(self, x, y, numResidents): Building.__init__(self, x, y, layer) self.numResidents = numResidents
我将如何使用声明将其转换为SQLAlchemy? 那么,我将如何查询哪些build筑物在x>5
和y>3
? 或者哪个住宅楼只有一个居民?
select如何表示inheritance主要是数据库devise问题。 对于性能单表inheritance通常是最好的。 从良好的数据库devise来看,join表inheritance是比较好的。 联合表inheritance使您可以将外键转换为数据库实施的子类,对子类字段使用非空约束要简单得多。 具体的表inheritance是两个世界中最糟糕的。
声明式单表inheritance设置如下所示:
class Building(Base): __tablename__ = 'building' id = Column(Integer, primary_key=True) building_type = Column(String(32), nullable=False) x = Column(Float, nullable=False) y = Column(Float, nullable=False) __mapper_args__ = {'polymorphic_on': building_type} class Commercial(Building): __mapper_args__ = {'polymorphic_identity': 'commercial'} business = Column(String(50)) class Residential(Building): __mapper_args__ = {'polymorphic_identity': 'residential'} num_residents = Column(Integer)
为了使它join表inheritance,你需要添加
__tablename__ = 'commercial' id = Column(None, ForeignKey('building.id'), primary_key=True)
到子类。
查询与两种方法大多相同:
# buildings that are within x>5 and y>3 session.query(Building).filter((Building.x > 5) & (Building.y > 3)) # Residential buildings that have only 1 resident session.query(Residential).filter(Residential.num_residents == 1)
要控制哪些字段被加载,你可以使用query.with_polymorphic()
方法。
对于使用数据映射inheritance来考虑最重要的事情是,你是否真的需要inheritance,或者可以使用聚合。 如果您需要改变build筑物的types,或者您的build筑物可以同时具有商业和住宅方面,那么inheritance将是一种痛苦。 在这种情况下,商业和住宅方面通常会更好。
antAasma的解决scheme更加优雅,但是如果您将您的类定义与您的表定义有意分离,则需要使用映射函数将您的类映射到您的表。 在你定义你的类之后,你需要定义你的表格:
building = Table('building', metadata, Column('id', Integer, primary_key=True), Column('x', Integer), Column('y', Integer), ) commercial = Table('commercial', metadata, Column('building_id', Integer, ForeignKey('building.id'), primary_key=True), Column('business', String(50)), ) residential = Table('residential', metadata, Column('building_id', Integer, ForeignKey('building.id'), primary_key=True), Column('numResidents', Integer), )
然后,您可以将表映射到类:
mapper(Building, building) mapper(Commercial, commercial, inherits=Building, polymorphic_identity='commercial') mapper(Residential, residential, inherits=Building, polymorphic_identity='residential')
然后与antAasma描述的完全相同的方式与类进行交互。