映射类继承层次结构¶

SQLAlchemy支持三种继承形式: 单表继承 ,其中几种类型的类由一个表表示, 具体的表继承 ,其中每种类型的类都由独立的表表示,并且 联接表继承 ,其中类层次结构在依赖表中被分解,每个类都由其自己的表表示,该表只包含该类的本地属性。

最常见的继承形式是单表和联接表,而具体的继承则面临更多的配置挑战。

在继承关系中配置映射器时,SQLAlchemy可以加载元素 polymorphically ,表示单个查询可以返回多个类型的对象。

参见

继承映射方法 -连接、单一和具体继承的完整示例

联接表继承

在联合表继承中,沿着类层次结构的每个类都由一个不同的表表示。查询层次结构中的特定子类将沿其继承路径中的所有表呈现为SQL联接。如果查询的类是基类,则 默认行为是只包括基表 在select语句中。在所有情况下,为给定行实例化的最终类都由鉴别器列或对基表有效的表达式确定。加载子类时 only 对于基表,结果对象将首先填充基属性;子类的本地属性将 lazy load 当它们被访问时。另外,还有一些选项可以更改默认行为,允许查询前面包含与多个表/子类对应的列。

联合继承层次结构中的基类配置了其他参数,这些参数将引用多态鉴别器列以及基类的标识符:

class Employee(Base):
    __tablename__ = 'employee'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    type = Column(String(50))

    __mapper_args__ = {
        'polymorphic_identity':'employee',
        'polymorphic_on':type
    }

上面,一个附加的列 type 被确定为 鉴别器 ,使用 mapper.polymorphic_on 参数。此列将存储一个值,该值指示行中表示的对象类型。列可以是任何数据类型,但字符串和整数是最常见的。

虽然多态性鉴别器表达不是严格必要的,但如果需要多态性加载,则需要它。在基表上建立一个简单的列是实现这一点的最简单方法,但是非常复杂的继承映射甚至可以将SQL表达式(如case语句)配置为多态鉴别器。

注解

目前, 只能为整个继承层次结构配置一个鉴别器列或SQL表达式 ,通常位于层次结构中最基本的类上。“尚不支持级联的“多态鉴别器表达式”。

我们下一个定义 EngineerManager 亚类 Employee . 每个列都包含表示它们所表示的子类唯一属性的列。每个表还必须包含主键列(或列),以及对父表的外键引用::

class Engineer(Employee):
    __tablename__ = 'engineer'
    id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
    engineer_name = Column(String(30))

    __mapper_args__ = {
        'polymorphic_identity':'engineer',
    }

class Manager(Employee):
    __tablename__ = 'manager'
    id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
    manager_name = Column(String(30))

    __mapper_args__ = {
        'polymorphic_identity':'manager',
    }

最常见的情况是,外键约束与主键本身建立在同一列或同一列上,但这不是必需的;也可以使与主键不同的列通过外键引用父级。从基表到子类构造联接的方式也可以直接定制,但这是很少必要的。

联接的继承主键

联合表继承配置的一个自然效果是,任何映射对象的标识都可以完全由基表中的行来确定。这有明显的优点,因此sqlAlchemy总是将联接继承类的主键列视为仅基表的主键列。也就是说, id 两列 engineermanager 表不用于定位 EngineerManager 对象-仅限中的值 employee.id 被认为是。 engineer.idmanager.id 当然,在语句中确定父行后,它们仍然对模式整体的正确操作至关重要,因为它们用于定位联接行。

连接继承映射完成后,查询 Employee 将返回 EmployeeEngineerManager 对象。新保存的 EngineerManagerEmployee 对象将自动填充 employee.type 在这种情况下具有正确“discriminator”值的列 "engineer""manager""employee" ,视情况而定。

与联合继承的关系

联接表继承完全支持关系。涉及已联接继承类的关系应以层次结构中也对应于外键约束的类为目标;在下面,作为 employee 表具有返回到的外键约束 company 表中,在 CompanyEmployee ::

class Company(Base):
    __tablename__ = 'company'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    employees = relationship("Employee", back_populates="company")

class Employee(Base):
    __tablename__ = 'employee'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    type = Column(String(50))
    company_id = Column(ForeignKey('company.id'))
    company = relationship("Company", back_populates="employees")

    __mapper_args__ = {
        'polymorphic_identity':'employee',
        'polymorphic_on':type
    }

class Manager(Employee):
    # ...

class Engineer(Employee):
    # ...

如果外键约束位于对应于子类的表上,那么关系应该以该子类为目标。在下面的示例中,有一个外键约束来自 managercompany ,因此在 ManagerCompany 班级:

class Company(Base):
    __tablename__ = 'company'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    managers = relationship("Manager", back_populates="company")

class Employee(Base):
    __tablename__ = 'employee'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    type = Column(String(50))

    __mapper_args__ = {
        'polymorphic_identity':'employee',
        'polymorphic_on':type
    }

class Manager(Employee):
    __tablename__ = 'manager'
    id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
    manager_name = Column(String(30))

    company_id = Column(ForeignKey('company.id'))
    company = relationship("Company", back_populates="managers")

    __mapper_args__ = {
        'polymorphic_identity':'manager',
    }

class Engineer(Employee):
    # ...

上面, Manager 班级将有一个 Manager.company 属性; Company 将有一个 Company.managers 总是针对 employeemanager 表格放在一起。

正在加载联接的继承映射

参见章节 正在加载继承层次结构正在加载具有联接表继承的对象 对于继承加载技术的背景,包括要在映射器配置时和查询时查询的表的配置。

单表继承

单表继承表示单表中所有子类的所有属性。具有该类独有属性的特定子类将在表中的列中持久化这些属性,否则,如果该行引用不同类型的对象,这些列将为空。

查询层次结构中的特定子类将呈现为对基表的选择,该基表将包含一个WHERE子句,该子句将行限制为那些在鉴别器列或表达式中具有特定值的行。

与联接表继承相比,单表继承具有简单的优点;查询效率更高,因为只有一个表需要参与,才能加载每个表示类的对象。

单表继承配置与联接表继承非常相似,只是基类指定了 __tablename__ . 基表上还需要一个鉴别器列,这样类就可以彼此区分。

即使子类共享其所有属性的基表,在使用声明性时, Column 对象仍然可以在子类上指定,这表示该列只映射到该子类; Column 将应用于同一基础 Table 对象:

class Employee(Base):
    __tablename__ = 'employee'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    type = Column(String(20))

    __mapper_args__ = {
        'polymorphic_on':type,
        'polymorphic_identity':'employee'
    }

class Manager(Employee):
    manager_data = Column(String(50))

    __mapper_args__ = {
        'polymorphic_identity':'manager'
    }

class Engineer(Employee):
    engineer_info = Column(String(50))

    __mapper_args__ = {
        'polymorphic_identity':'engineer'
    }

注意,派生类管理器和工程师的映射器省略了 __tablename__ ,指示它们没有自己的映射表。

与单表继承的关系

单表继承完全支持关系。配置的方式与联接继承的方式相同;外键属性应位于关系的“外部”端的同一类上:

class Company(Base):
    __tablename__ = 'company'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    employees = relationship("Employee", back_populates="company")

class Employee(Base):
    __tablename__ = 'employee'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    type = Column(String(50))
    company_id = Column(ForeignKey('company.id'))
    company = relationship("Company", back_populates="employees")

    __mapper_args__ = {
        'polymorphic_identity':'employee',
        'polymorphic_on':type
    }


class Manager(Employee):
    manager_data = Column(String(50))

    __mapper_args__ = {
        'polymorphic_identity':'manager'
    }

class Engineer(Employee):
    engineer_info = Column(String(50))

    __mapper_args__ = {
        'polymorphic_identity':'engineer'
    }

此外,与联合继承的情况一样,我们可以创建涉及特定子类的关系。查询时,select语句将包含一个WHERE子句,该子句将类选择限制为该子类或子类:

class Company(Base):
    __tablename__ = 'company'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    managers = relationship("Manager", back_populates="company")

class Employee(Base):
    __tablename__ = 'employee'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    type = Column(String(50))

    __mapper_args__ = {
        'polymorphic_identity':'employee',
        'polymorphic_on':type
    }


class Manager(Employee):
    manager_name = Column(String(30))

    company_id = Column(ForeignKey('company.id'))
    company = relationship("Company", back_populates="managers")

    __mapper_args__ = {
        'polymorphic_identity':'manager',
    }


class Engineer(Employee):
    engineer_info = Column(String(50))

    __mapper_args__ = {
        'polymorphic_identity':'engineer'
    }

上面, Manager 班级将有一个 Manager.company 属性; Company 将有一个 Company.managers 总是针对 employee 使用附加的WHERE子句将行限制为 type = 'manager' .

加载单个继承映射

单表继承的加载技术与用于连接表继承的加载技术基本相同,并且这两种映射类型之间提供了高度的抽象性,以便在它们之间切换以及在单个层次结构中混合它们(只需省略 __tablename__ 从属于单一继承的子类)。参见章节 正在加载继承层次结构加载具有单表继承的对象 有关继承加载技术的文档,包括要在映射器配置时和查询时查询的类的配置。

具体的表继承

具体继承将每个子类映射到它自己的不同表,每个表包含生成该类实例所需的所有列。默认情况下,具体的继承配置以非多态方式查询;对特定类的查询将只查询该类的表,并且只返回该类的实例。具体类的多态加载是通过在映射器中配置一个特殊的选择来实现的,该选择通常作为所有表的联合产生。

警告

具体的表继承是 更复杂的是 而不是联合的或单表继承,并且 功能更加有限 特别是关于将其用于关系、渴望加载和多态加载。当使用多态性时,它产生 非常大的查询 使用的联合不如简单的联接效果好。强烈建议,如果需要关系加载和多态加载的灵活性,则尽可能使用联接表或单表继承。如果不需要多态加载,那么如果每个类完全引用自己的表,就可以使用普通的非继承映射。

尽管连接表继承和单表继承在“多态”加载方面非常流利,但在具体继承中,这是一个更为棘手的问题。因此,当 不需要多态加载 . 建立涉及具体继承类的关系也更加困难。

要使用具体继承建立类,请添加 mapper.concrete 中的参数 __mapper_args__ . 这向声明性和映射指示不应将超类表视为映射的一部分:

class Employee(Base):
    __tablename__ = 'employee'

    id = Column(Integer, primary_key=True)
    name = Column(String(50))

class Manager(Employee):
    __tablename__ = 'manager'

    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    manager_data = Column(String(50))

    __mapper_args__ = {
        'concrete': True
    }

class Engineer(Employee):
    __tablename__ = 'engineer'

    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    engineer_info = Column(String(50))

    __mapper_args__ = {
        'concrete': True
    }

应注意两个关键点:

混凝土多晶加载形态

具有具体继承的多态加载要求针对每个应该具有多态加载的基类配置专门的select。此select需要能够单独访问所有映射表,并且通常是使用sqlAlchemy助手构造的union语句。 polymorphic_union() .

正如在 正在加载继承层次结构 ,可以将任何类型的映射器继承配置配置为默认情况下使用 mapper.with_polymorphic 争论。当前公共API要求在 Mapper 第一次施工时。

但是,在声明性的情况下,映射器和 Table 一旦定义了映射类,就会立即创建映射类。这意味着 mapper.with_polymorphic 还无法提供参数,因为 Table 与子类相对应的对象尚未定义。

有几个策略可以解决这个循环,但是声明性提供了助手类。 ConcreteBaseAbstractConcreteBase 在幕后处理这个问题。

使用 ConcreteBase 我们可以用与其他形式的继承映射几乎相同的方式设置具体映射:

from sqlalchemy.ext.declarative import ConcreteBase

class Employee(ConcreteBase, Base):
    __tablename__ = 'employee'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))

    __mapper_args__ = {
        'polymorphic_identity': 'employee',
        'concrete': True
    }

class Manager(Employee):
    __tablename__ = 'manager'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    manager_data = Column(String(40))

    __mapper_args__ = {
        'polymorphic_identity': 'manager',
        'concrete': True
    }

class Engineer(Employee):
    __tablename__ = 'engineer'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    engineer_info = Column(String(40))

    __mapper_args__ = {
        'polymorphic_identity': 'engineer',
        'concrete': True
    }

上面,声明性设置了 Employee 在映射器“初始化”时初始化;这是用于解析其他依赖映射器的映射器的最新配置步骤。这个 ConcreteBase 助手使用 polymorphic_union() 函数在设置所有其他类之后创建所有具体映射表的联合,然后使用现有的基类映射器配置此语句。

选择后,多态联合生成如下查询:

session.query(Employee).all()
SELECT pjoin.id AS pjoin_id, pjoin.name AS pjoin_name, pjoin.type AS pjoin_type, pjoin.manager_data AS pjoin_manager_data, pjoin.engineer_info AS pjoin_engineer_info FROM ( SELECT employee.id AS id, employee.name AS name, CAST(NULL AS VARCHAR(50)) AS manager_data, CAST(NULL AS VARCHAR(50)) AS engineer_info, 'employee' AS type FROM employee UNION ALL SELECT manager.id AS id, manager.name AS name, manager.manager_data AS manager_data, CAST(NULL AS VARCHAR(50)) AS engineer_info, 'manager' AS type FROM manager UNION ALL SELECT engineer.id AS id, engineer.name AS name, CAST(NULL AS VARCHAR(50)) AS manager_data, engineer.engineer_info AS engineer_info, 'engineer' AS type FROM engineer ) AS pjoin

上面的联合查询需要为每个子表生成“空”列,以便容纳那些不是该特定子类成员的列。

抽象的具体类

到目前为止,所示的具体映射既显示了子类,也显示了映射到各个表的基类。在具体的继承用例中,通常不在数据库中表示基类,只表示子类。换句话说,基类是“抽象的”。

通常,当您希望将两个不同的子类映射到单个表,并且不映射基类时,这很容易实现。使用声明性时,只需使用 __abstract__ 指标:

class Employee(Base):
    __abstract__ = True

class Manager(Employee):
    __tablename__ = 'manager'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    manager_data = Column(String(40))

    __mapper_args__ = {
        'polymorphic_identity': 'manager',
    }

class Engineer(Employee):
    __tablename__ = 'engineer'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    engineer_info = Column(String(40))

    __mapper_args__ = {
        'polymorphic_identity': 'engineer',
    }

上面,我们实际上并没有使用sqlachemy的继承映射工具;我们可以加载和持久化 ManagerEngineer 通常情况下。但是当我们需要的时候情况会改变 多态查询 也就是说,我们想发射 session.query(Employee) 并取回一系列 ManagerEngineer 实例。这使我们回到具体继承领域,我们必须针对 Employee 为了达到这个目的。

映射器始终可以选择

在sqlAlchemy中,类的映射器总是需要引用一些“可选的”,通常是 Table 但也可以指 select() 对象也一样。虽然看起来“单表继承”映射器没有映射到表,但实际上,这些映射器隐式地引用了由超类映射的表。

为了修改我们的具体继承示例以说明能够进行多态加载的“抽象”基,我们将只有一个 engineer 和A manager 表与否 employee 然而,表 Employee 映射器将直接映射到“多态联合”,而不是在本地将其指定到 mapper.with_polymorphic 参数。

为了帮助实现这一点,声明性提供了 ConcreteBase 类称为 AbstractConcreteBase 自动实现:

from sqlalchemy.ext.declarative import AbstractConcreteBase

class Employee(AbstractConcreteBase, Base):
    pass

class Manager(Employee):
    __tablename__ = 'manager'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    manager_data = Column(String(40))

    __mapper_args__ = {
        'polymorphic_identity': 'manager',
        'concrete': True
    }

class Engineer(Employee):
    __tablename__ = 'engineer'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    engineer_info = Column(String(40))

    __mapper_args__ = {
        'polymorphic_identity': 'engineer',
        'concrete': True
    }

这个 AbstractConcreteBase helper类的内部进程比 ConcreteBase ,其中必须延迟基类的整个映射,直到所有子类都已声明。对于上面这样的映射,只有 ManagerEngineer 可能被持久化;查询 Employee 类将始终生成 ManagerEngineer 对象。

参见

具体的表继承 -在声明性参考文档中

经典和半经典混凝土多晶型构形

说明的声明性配置 ConcreteBaseAbstractConcreteBase 相当于使用 polymorphic_union() 明确地。这些构型利用 Table 对象,以便首先创建“多态联合”,然后将其应用于映射。这里对这些进行了说明,以阐明 polymorphic_union() 在映射方面的函数。

A semi-classical mapping 例如,使用声明性,但建立 Table 单独对象:

metadata = Base.metadata

employees_table = Table(
    'employee', metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String(50)),
)

managers_table = Table(
    'manager', metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String(50)),
    Column('manager_data', String(50)),
)

engineers_table = Table(
    'engineer', metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String(50)),
    Column('engineer_info', String(50)),
)

接下来,使用 polymorphic_union() ::

from sqlalchemy.orm import polymorphic_union

pjoin = polymorphic_union({
    'employee': employees_table,
    'manager': managers_table,
    'engineer': engineers_table
}, 'type', 'pjoin')

与上述 Table 对象,映射可以使用“半经典”样式生成,其中我们将声明性与 __table__ 论点;我们上面的多态联合是通过 __mapper_args__mapper.with_polymorphic 参数::

class Employee(Base):
    __table__ = employee_table
    __mapper_args__ = {
        'polymorphic_on': pjoin.c.type,
        'with_polymorphic': ('*', pjoin),
        'polymorphic_identity': 'employee'
    }

class Engineer(Employee):
    __table__ = engineer_table
    __mapper_args__ = {
        'polymorphic_identity': 'engineer',
        'concrete': True}

class Manager(Employee):
    __table__ = manager_table
    __mapper_args__ = {
        'polymorphic_identity': 'manager',
        'concrete': True}

交替,相同 Table 对象可以完全“经典”样式使用,根本不使用声明性。类似于声明性提供的构造函数的说明如下:

class Employee(object):
    def __init__(self, **kw):
        for k in kw:
            setattr(self, k, kw[k])

class Manager(Employee):
    pass

class Engineer(Employee):
    pass

employee_mapper = mapper(Employee, pjoin,
                                    with_polymorphic=('*', pjoin),
                                    polymorphic_on=pjoin.c.type)
manager_mapper = mapper(Manager, managers_table,
                                    inherits=employee_mapper,
                                    concrete=True,
                                    polymorphic_identity='manager')
engineer_mapper = mapper(Engineer, engineers_table,
                                    inherits=employee_mapper,
                                    concrete=True,
                                    polymorphic_identity='engineer')

“抽象”示例也可以使用“半经典”或“经典”样式进行映射。不同之处在于,不是将“多态结合”应用于 mapper.with_polymorphic 参数,我们直接将其应用于我们最基本的映射器上的映射可选项。半经典映射如下图所示:

from sqlalchemy.orm import polymorphic_union

pjoin = polymorphic_union({
    'manager': managers_table,
    'engineer': engineers_table
}, 'type', 'pjoin')

class Employee(Base):
    __table__ = pjoin
    __mapper_args__ = {
        'polymorphic_on': pjoin.c.type,
        'with_polymorphic': '*',
        'polymorphic_identity': 'employee'
    }

class Engineer(Employee):
    __table__ = engineer_table
    __mapper_args__ = {
        'polymorphic_identity': 'engineer',
        'concrete': True}

class Manager(Employee):
    __table__ = manager_table
    __mapper_args__ = {
        'polymorphic_identity': 'manager',
        'concrete': True}

以上,我们使用 polymorphic_union() 和以前一样,只是我们省略了 employee

参见

经典映射 -“经典”映射的背景信息

与具体继承的关系

在具体的继承场景中,映射关系具有挑战性,因为不同的类不共享表。如果关系只涉及特定的类,例如 Company 在前面的示例中, Manager ,不需要特殊步骤,因为这只是两个相关表。

然而,如果 Company 是一对多的关系 Employee ,指示集合可以同时包含 EngineerManager 对象,这意味着 Employee 必须具有多态加载功能,并且每个要关联的表都必须具有返回到 company 表。这种配置的示例如下:

from sqlalchemy.ext.declarative import ConcreteBase


class Company(Base):
    __tablename__ = 'company'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    employees = relationship("Employee")


class Employee(ConcreteBase, Base):
    __tablename__ = 'employee'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    company_id = Column(ForeignKey('company.id'))

    __mapper_args__ = {
        'polymorphic_identity': 'employee',
        'concrete': True
    }


class Manager(Employee):
    __tablename__ = 'manager'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    manager_data = Column(String(40))
    company_id = Column(ForeignKey('company.id'))

    __mapper_args__ = {
        'polymorphic_identity': 'manager',
        'concrete': True
    }


class Engineer(Employee):
    __tablename__ = 'engineer'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    engineer_info = Column(String(40))
    company_id = Column(ForeignKey('company.id'))

    __mapper_args__ = {
        'polymorphic_identity': 'engineer',
        'concrete': True
    }

下一个具有具体继承和关系的复杂性涉及到当我们想要一个或全部 EmployeeManagerEngineer 回指自己 Company . 在这种情况下,sqlAlchemy在 relationship() 放在 Employee 哪些链接 Company 不起作用 反对 ManagerEngineer 类,在实例级别执行时。相反,一个独特的 relationship() 必须应用于每个类。为了在三个独立的关系中实现双向行为,这三个关系是 Company.employees , the relationship.back_populates 参数在每个关系之间使用::

from sqlalchemy.ext.declarative import ConcreteBase


class Company(Base):
    __tablename__ = 'company'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    employees = relationship("Employee", back_populates="company")


class Employee(ConcreteBase, Base):
    __tablename__ = 'employee'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    company_id = Column(ForeignKey('company.id'))
    company = relationship("Company", back_populates="employees")

    __mapper_args__ = {
        'polymorphic_identity': 'employee',
        'concrete': True
    }


class Manager(Employee):
    __tablename__ = 'manager'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    manager_data = Column(String(40))
    company_id = Column(ForeignKey('company.id'))
    company = relationship("Company", back_populates="employees")

    __mapper_args__ = {
        'polymorphic_identity': 'manager',
        'concrete': True
    }


class Engineer(Employee):
    __tablename__ = 'engineer'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    engineer_info = Column(String(40))
    company_id = Column(ForeignKey('company.id'))
    company = relationship("Company", back_populates="employees")

    __mapper_args__ = {
        'polymorphic_identity': 'engineer',
        'concrete': True
    }

上述限制与当前的实现有关,包括具体的继承类不共享超类的任何属性,因此需要建立不同的关系。

加载具体的继承映射

使用具体继承进行加载的选项是有限的;通常,如果在映射器上使用一个声明性具体混合配置了多态加载,则在当前的sqlAlchemy版本中,不能在查询时对其进行修改。通常情况下, orm.with_polymorphic() 函数可以覆盖混凝土使用的加载样式,但是由于当前的限制,目前还不支持这种方式。