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()
生成的“多态” selectable,并且它自身不执行任何持久化操作。 与ConcreteBase
比较,后者将其直接继承类映射到实际的Table
,该表直接存储行。注意
AbstractConcreteBase
延迟基类的映射器创建,直到定义了所有子类为止,因为它需要针对包含所有子类表的可选对象创建映射。 为了实现这一点,它等待 映射器配置事件 发生,此时它扫描所有已配置的子类,并设置一个将一次查询所有子类的映射。虽然此事件通常会自动调用,但在
AbstractConcreteBase
的情况下,如果第一个操作是对该基类的查询,则可能需要在定义 所有 子类映射后显式调用它。 为此,一旦配置了所有所需的类,就可以调用registry.configure()
方法,该方法在与特定声明式基类的关系中可用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()
抽象基类由声明式以特殊方式处理;在类配置时,它的行为类似于声明式 mixin 或
__abstract__
基类。 一旦配置了类并生成了映射,它就会被自身映射,但在其所有后代之后。 这是一种非常独特的映射系统,在任何其他 SQLAlchemy API 功能中都找不到。使用这种方法,我们可以指定将在映射子类上发生的列和属性,就像我们在 Mixin 和自定义基类 中通常做的那样
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
比较。示例
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 版本中新增: 添加了
_concrete_discriminator_name
属性到ConcreteBase
,以便可以自定义虚拟鉴别器列名称。在版本 1.4.2 中更改:
_concrete_discriminator_name
属性只需要放置在最底层的基类上,即可对所有子类产生正确的效果。 如果映射的列名与鉴别器名称冲突,则现在会引发显式错误消息,而在 1.3.x 系列中,会发出一些警告,然后生成无用的查询。
- class 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 可以应用于单个类,用作声明式基类的基础,或在自定义抽象类中使用。 使用抽象基类允许仅为特定的 prepare 步骤准备类的子集,这对于使用多个引擎的应用程序是必要的。 例如,如果应用程序有两个引擎,则可以使用两个基类,并分别准备每个基类,例如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¶ 反射所有当前
DeferredReflection
子类的Table
对象- 参数:
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 创建。 文档上次生成时间: 2025 年 3 月 11 日星期二下午 02:40:17 EDT