SQLAlchemy 2.0 文档
声明式扩展¶
特定于 声明式 映射 API 的扩展。
版本 1.4 中变更: 声明式扩展的大部分内容现在已集成到 SQLAlchemy ORM 中,可以从 sqlalchemy.orm
命名空间导入。有关新文档,请参阅 声明式映射。有关变更概述,请参阅 声明式现在已集成到 ORM 中,并具有新功能.
对象名称 | 描述 |
---|---|
用于“具体”声明式映射的辅助类。 |
|
用于“具体”声明式映射的辅助类。 |
|
用于基于延迟反射步骤构建映射的辅助类。 |
- class sqlalchemy.ext.declarative.AbstractConcreteBase¶
用于“具体”声明式映射的辅助类。
AbstractConcreteBase
将自动使用polymorphic_union()
函数,针对所有映射为该类子类的表。该函数通过__declare_first__()
函数调用,该函数本质上是before_configured()
事件的钩子。AbstractConcreteBase
为其直接继承类应用Mapper
,就像任何其他声明式映射类一样。但是,Mapper
未映射到任何特定的Table
对象。相反,它直接映射到由polymorphic_union()
生成的“多态”可选择对象,并且本身不执行任何持久化操作。与ConcreteBase
相比,ConcreteBase
将其直接继承类映射到实际存储行的Table
。注意
AbstractConcreteBase
将基类的映射器创建延迟到所有子类定义完成后,因为它需要针对包含所有子类表的可选择对象创建映射。为了实现这一点,它将等待 **映射器配置事件** 发生,此时它将扫描所有配置的子类并设置一个映射,该映射将同时查询所有子类。虽然此事件通常会自动调用,但在
AbstractConcreteBase
的情况下,可能需要在 **所有** 子类映射定义后显式调用它,如果第一个操作是针对该基类进行查询。为此,一旦所有所需类都已配置,可以使用registry.configure()
方法调用正在使用的registry
,它与特定的声明式基类相关。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()
抽象基类由声明式以特殊方式处理;在类配置时,它的行为类似于声明式混合或
__abstract__
基类。一旦类配置完成并生成了映射,它将映射自身,但在此之前要先映射所有其后代。这是一个非常独特的映射系统,在 SQLAlchemy 的其他 API 功能中找不到。使用这种方法,我们可以像在 混合和自定义基类 中那样,指定将在映射的子类上执行的列和属性。
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()
但是,当我们使用映射时,
Manager
和Employee
都将具有独立可用的.company
属性session.execute( select(Employee).filter(Employee.company.has(id=5)) )
- 参数:
strict_attrs¶ –
当在基类上指定时,将启用“严格”属性模式,该模式试图将基类上的 ORM 映射属性限制为仅那些直接存在的属性,同时仍保留“多态”加载行为。
版本 2.0 中新增。
- class sqlalchemy.ext.declarative.ConcreteBase¶
用于“具体”声明式映射的辅助类。
ConcreteBase
将自动使用polymorphic_union()
函数,针对所有映射为该类子类的表。该函数通过__declare_last__()
函数调用,该函数本质上是after_configured()
事件的钩子。ConcreteBase
为该类本身生成一个映射的表。与AbstractConcreteBase
相比,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()
使用的鉴别器列的名称默认为type
。为了适应映射的使用场景,其中映射表的实际列已命名为type
,可以通过设置_concrete_discriminator_name
属性来配置鉴别器名称。class Employee(ConcreteBase, Base): _concrete_discriminator_name = '_concrete_discriminator'
版本 1.3.19 中新增: 为
ConcreteBase
添加了_concrete_discriminator_name
属性,以便可以自定义虚拟鉴别器列的名称。版本 1.4.2 中变更: 仅需在最基类的类上放置
_concrete_discriminator_name
属性,即可对所有子类产生正确的影响。如果映射的列名与鉴别器名称冲突,现在会引发明确的错误消息,而在 1.3.x 系列中,会发出一些警告,然后会生成一个无用的查询。
- class sqlalchemy.ext.declarative.DeferredReflection¶
用于基于延迟反射步骤构建映射的辅助类。
通常,声明式可以通过反射使用,方法是使用
Table
对象,并将 autoload_with=engine 设置为声明式类上的__table__
属性。需要注意的是,Table
必须被完全反射,或者至少拥有一个主键列,在构建普通声明式映射的时候,意味着Engine
必须在类声明时可用。DeferredReflection
混合类将映射器的构建推迟到稍后的时间,直到调用一个特定的方法,该方法首先会反射到目前为止创建的所有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
混合类可以应用于单个类,用作声明式基类的基础,也可以用在自定义抽象类中。使用抽象基类允许仅准备特定准备步骤的类子集,这对于使用多个引擎的应用程序是必需的。例如,如果一个应用程序有两个引擎,你可能会使用两个基类,并分别准备它们,例如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.
上面,
ReflectedOne
和ReflectedTwo
的类层次结构可以单独配置。ReflectedOne.prepare(engine_one) ReflectedTwo.prepare(engine_two)
成员
另请参阅
使用 DeferredReflection - 在 使用声明式配置表格 部分。
-
classmethod
sqlalchemy.ext.declarative.DeferredReflection.
prepare(bind: Engine | Connection, **reflect_kw: Any) → None¶ 反射所有
Table
对象,适用于所有当前DeferredReflection
子类。- 参数:
bind¶ –
Engine
或Connection
实例..versionchanged:: 2.0.16 也接受
Connection
。**reflect_kw¶ –
传递给
MetaData.reflect()
的其他关键字参数,例如MetaData.reflect.views
。版本 2.0.16 新增。
-
classmethod
flambé! 龙和 炼金术士 图像设计由 Rotem Yaari 创建并慷慨捐赠。
使用 Sphinx 7.2.6 创建。文档最后生成时间:Fri 08 Nov 2024 08:41:19 AM EST