声明式扩展


特定于 Declarative 的扩展 映射 API 的 API 中。


在 1.4 版本发生变更: Declarative 扩展的绝大多数现在是 集成到 SQLAlchemy ORM 中,并且可以从 sqlalchemy.orm 命名空间。 请参阅文档 新文档的声明式映射。有关更改的概述,请参阅Declarative 现已集成到具有新功能的 ORM 中


对象名称

描述


抽象混凝土基础


用于 'concrete' 声明性映射的帮助程序类。


混凝土基地


用于 'concrete' 声明性映射的帮助程序类。


DeferredReflection (延迟反射)


一个帮助程序类,用于基于延迟反射步骤构造映射。


sqlalchemy.ext.declarative 中。AbstractConcreteBase


用于 'concrete' 声明性映射的帮助程序类。


AbstractConcreteBase 将使用 polymorphic_union() 函数,针对映射为子类的所有表 添加到此类。 该函数通过 __declare_first__() 函数,它本质上是 before_configured() 事件的钩子。


AbstractConcreteBaseMapper 应用于其直接继承的类,就像任何其他声明性映射类一样。但是,Mapper 未映射到任何特定的 Table 对象。 相反,它是 直接映射到由 polymorphic_union() 中执行的,并且不会自行执行持久性作。与 ConcreteBase 相比,ConcreteBase 将其 立即将类继承到实际的 Table 直接存储行。


注意


AbstractConcreteBase 会延迟 Mapper 的 base 类,直到定义了所有子类, 因为它需要创建一个针对 Selectable 的映射,该 Map 将包括 所有子类表。 为了实现这一点,它会等待 mapper 配置事件,此时它会扫描所有已配置的子类并设置一个映射,该映射将同时查询所有子类。


虽然此事件通常是自动调用的,但在 AbstractConcreteBase,则可能需要在所有子类映射都定义完后显式调用它,如果第一个 operation 是针对此基类的查询。为此,一旦 所需的类已配置完毕,则 registry.configure() 方法 in use 中,它相对于特定的 声明性基类:

Base.registry.configure()


例:

from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.ext.declarative import AbstractConcreteBase


class Base(DeclarativeBase):
    pass


class Employee(AbstractConcreteBase, Base):
    pass


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

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


Base.registry.configure()


抽象基类由 declarative 以特殊方式处理;在 class 配置时,它的行为类似于声明性 mixin 或 __abstract__ 基类。一旦配置了类并生成了 Maps,它就会被映射自身,但在它的所有后代之后。这是一个非常独特的映射系统,在任何其他 SQLAlchemy API 功能中都找不到。


使用这种方法,我们可以指定将在映射的子类上发生的列和属性,就像我们通常在 Mixin 和 Custom Base Classes 中所做的那样:

from sqlalchemy.ext.declarative import AbstractConcreteBase


class Company(Base):
    __tablename__ = "company"
    id = Column(Integer, primary_key=True)


class Employee(AbstractConcreteBase, Base):
    strict_attrs = True

    employee_id = Column(Integer, primary_key=True)

    @declared_attr
    def company_id(cls):
        return Column(ForeignKey("company.id"))

    @declared_attr
    def company(cls):
        return relationship("Company")


class Manager(Employee):
    __tablename__ = "manager"

    name = Column(String(50))
    manager_data = Column(String(40))

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


Base.registry.configure()


然而,当我们使用我们的映射时,ManagerEmployee 将具有一个可独立使用的 .company 属性:

session.execute(select(Employee).filter(Employee.company.has(id=5)))

参数

strict_attrs


在基类上指定时,将启用“严格”属性模式,该模式尝试将基类上的 ORM 映射属性限制为仅立即存在的属性,同时仍保留“多态”加载行为。


2.0 版的新Function。


sqlalchemy.ext.declarative 中。ConcreteBase


用于 'concrete' 声明性映射的帮助程序类。


ConcreteBase 将使用 polymorphic_union() 函数,针对映射为子类的所有表 添加到此类。 该函数通过 __declare_last__() 函数,它本质上是 after_configured() 事件的钩子。


ConcreteBase 为类本身生成一个映射表。相比之下,AbstractConcreteBase 则没有。


例:

from sqlalchemy.ext.declarative import ConcreteBase


class Employee(ConcreteBase, Base):
    __tablename__ = "employee"
    employee_id = Column(Integer, primary_key=True)
    name = Column(String(50))
    __mapper_args__ = {
        "polymorphic_identity": "employee",
        "concrete": True,
    }


class Manager(Employee):
    __tablename__ = "manager"
    employee_id = Column(Integer, primary_key=True)
    name = Column(String(50))
    manager_data = Column(String(40))
    __mapper_args__ = {
        "polymorphic_identity": "manager",
        "concrete": True,
    }


polymorphic_union() 使用的鉴别器列的名称 默认为 name 类型。为了适应映射中的用例,其中映射表中的实际列已经是命名 type, 鉴别器名称可以通过设置 _concrete_discriminator_name 属性:

class Employee(ConcreteBase, Base):
    _concrete_discriminator_name = "_concrete_discriminator"


1.3.19 版本中的新功能: 添加了 _concrete_discriminator_name 属性设置为 ConcreteBase,以便可以自定义虚拟鉴别器列名。


在 1.4.2 版本发生变更: _concrete_discriminator_name 属性只需放在最基类上,即可对所有子类产生正确效果。现在,如果映射的列名与鉴别器名冲突,则会引发明确的错误消息,而在 1.3.x 系列中,会有一些警告,然后会生成无用的查询。


sqlalchemy.ext.declarative 中。DeferredReflection(延迟反射)¶


一个帮助程序类,用于基于延迟反射步骤构造映射。


通常,通过使用 autoload_with=engine 作为声明性类的 __table__ 属性来设置 Table 对象,声明性可以与反射一起使用。需要注意的是,Table 必须在构造正常声明性映射时完全反映,或者至少有一个主键列,这意味着 Engine 必须在类声明时可用。


DeferredReflection mixin 将映射器的构造移动到稍后的某个时间点,在调用一个首先反映所有 Table 的特定方法之后 到目前为止创建的对象。 类可以这样定义它:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative import DeferredReflection

Base = declarative_base()


class MyClass(DeferredReflection, Base):
    __tablename__ = "mytable"


在上图中,MyClass 尚未映射。 在一系列 类已按上述方式定义,所有表 可以反射,并使用 prepare() 中:

engine = create_engine("someengine://...")
DeferredReflection.prepare(engine)


DeferredReflection mixin 可以应用于单个类,用作声明性基本身的基础,或在自定义抽象类中使用。使用抽象基允许仅为特定准备步骤准备类的子集,这对于使用多个引擎的应用程序是必需的。例如,如果一个应用程序有两个引擎,您可以使用两个 base,并分别准备每个引擎,例如:

class ReflectedOne(DeferredReflection, Base):
    __abstract__ = True


class ReflectedTwo(DeferredReflection, Base):
    __abstract__ = True


class MyClass(ReflectedOne):
    __tablename__ = "mytable"


class MyOtherClass(ReflectedOne):
    __tablename__ = "myothertable"


class YetAnotherClass(ReflectedTwo):
    __tablename__ = "yetanothertable"


# ... etc.


在上面,ReflectedOneReflectedTwo 可以单独配置:

ReflectedOne.prepare(engine_one)
ReflectedTwo.prepare(engine_two)


成员


准备()


类方法 sqlalchemy.ext.declarative.DeferredReflection. preparebind:EngineConnection, **reflect_kw: Any None


反映所有当前 Table 对象 DeferredReflection 子类


参数