SqlAlchemy 2.0 中文文档(十)(3)https://developer.aliyun.com/article/1562917
下面,无论是MyClass
还是MySubClass
都将建立一个独特的id
列对象:
class HasIdMixin: @declared_attr.cascading def id(cls): if has_inherited_table(cls): return Column(ForeignKey("myclass.id"), primary_key=True) else: return Column(Integer, primary_key=True) class MyClass(HasIdMixin, Base): __tablename__ = "myclass" # ... class MySubClass(MyClass): """ """ # ...
上述配置的行为是,MySubClass
将引用其自己的id
列以及MyClass
下面命名为some_id
的属性。
另见
声明性继承
使用 _orm.declared_attr() 生成特定表继承列
attribute directive
将 declared_attr
标记为装饰声明性指令,如 __tablename__
或 __mapper_args__
。
declared_attr.directive
的目的严格是支持PEP 484类型工具,允许装饰的函数具有不使用 Mapped
通用类的返回类型,这在使用 declared_attr
用于列和映射属性时通常是不会发生的。在运行时,declared_attr.directive
返回未经修改的 declared_attr
类。
例如:
class CreateTableName: @declared_attr.directive def __tablename__(cls) -> str: return cls.__name__.lower()
2.0 版本中的新功能。
另请参见
使用 Mixins 组合映射层次结构
declared_attr
class sqlalchemy.orm.DeclarativeBase
用于声明性类定义的基类。
DeclarativeBase
允许以与类型检查器兼容的方式创建新的声明性基类:
from sqlalchemy.orm import DeclarativeBase class Base(DeclarativeBase): pass
上述 Base
类现在可用作新声明性映射的基类。超类利用 __init_subclass__()
方法设置新类,而不使用元类。
首次使用时,DeclarativeBase
类实例化一个新的 registry
用于与基类一起使用,假设未明确提供。DeclarativeBase
类支持类级属性,这些属性充当此注册表构建的参数;例如指示特定的 MetaData
集合以及 registry.type_annotation_map
的特定值:
from typing_extensions import Annotated from sqlalchemy import BigInteger from sqlalchemy import MetaData from sqlalchemy import String from sqlalchemy.orm import DeclarativeBase bigint = Annotated[int, "bigint"] my_metadata = MetaData() class Base(DeclarativeBase): metadata = my_metadata type_annotation_map = { str: String().with_variant(String(255), "mysql", "mariadb"), bigint: BigInteger() }
可指定的类级属性包括:
参数:
metadata
– 可选的MetaData
集合。如果自动构造了一个registry
,则将使用该MetaData
集合来构造它。否则,本地的MetaData
集合将取代通过DeclarativeBase.registry
参数传递的现有registry
使用的集合。type_annotation_map
– 可选的类型注释映射,将传递给registry
作为registry.type_annotation_map
.registry
– 直接提供预先存在的registry
。
2.0 版本中的新功能:添加了DeclarativeBase
,以便可以以也被PEP 484类型检查器识别的方式构造声明性基类。因此,DeclarativeBase
和其他基于子类化的 API 应被视为取代先前的“由函数返回的类” API,即declarative_base()
和registry.generate_base()
,其中返回的基类不能被类型检查器识别,除非使用插件。
init 行为
在普通的 Python 类中,类层次结构中基本的 __init__()
方法是 object.__init__()
,不接受任何参数。然而,当首次声明DeclarativeBase
子类时,如果没有已经存在的 __init__()
方法,该类将被赋予一个 __init__()
方法,该方法链接到registry.constructor
构造函数;这是通常的声明性构造函数,将关键字参数分配给实例的属性,假定这些属性在类级别已经建立(即已映射,或者与描述符链接)。这个构造函数永远不会被映射类直接访问,除非通过显式调用 super(),因为映射类本身会直接得到一个 __init__()
方法,该方法调用registry.constructor
,所以在默认情况下独立于基本的 __init__()
方法的操作。
从版本 2.0.1 开始发生了变化:DeclarativeBase
现在具有默认构造函数,默认链接到 registry.constructor
,以便调用 super().__init__()
可以访问此构造函数。先前,由于一个实现错误,这个默认构造函数丢失了,调用 super().__init__()
将会调用 object.__init__()
。
DeclarativeBase
子类也可以声明一个显式的 __init__()
方法,该方法将在此级别替代 registry.constructor
函数的使用:
class Base(DeclarativeBase): def __init__(self, id=None): self.id = id
映射的类仍然不会隐式调用这个构造函数;只能通过调用 super().__init__()
来访问它:
class MyClass(Base): def __init__(self, id=None, name=None): self.name = name super().__init__(id=id)
请注意,这与诸如传统的 declarative_base()
等函数的行为不同;由这些函数创建的基类将始终为 __init__()
安装 registry.constructor
。
成员
mapper, mapper_args, table, table_args, tablename, metadata, registry
类签名
类 sqlalchemy.orm.DeclarativeBase
(sqlalchemy.inspection.Inspectable
)
attribute __mapper__: ClassVar[Mapper[Any]]
将特定类映射到的 Mapper
对象。
也可以使用 inspect()
获取,例如 inspect(klass)
。
attribute __mapper_args__: Any
传递给 Mapper
构造函数的参数字典。
另见
使用声明式的 Mapper 配置选项
attribute __table__: ClassVar[FromClause]
将特定子类映射到的 FromClause
。
这通常是 Table
的一个实例,但根据类的映射方式,也可能是其他类型的 FromClause
,比如 Subquery
。
另见
访问表和元数据
attribute __table_args__: Any
将传递给Table
构造函数的参数字典或元组。有关此集合特定结构的背景,请参阅声明式表配置。
另请参阅
声明式表配置
attribute __tablename__: Any
将生成的Table
对象分配的字符串名称,如果没有通过DeclarativeBase.__table__
直接指定。
另请参阅
使用 mapped_column()的声明式表
attribute metadata: ClassVar[MetaData]
指的是将用于新Table
对象的MetaData
集合。
另请参阅
访问表和元数据
attribute registry: ClassVar[registry]
指的是新Mapper
对象将关联的正在使用的registry
。
class sqlalchemy.orm.DeclarativeBaseNoMeta
与DeclarativeBase
相同,但不使用元类拦截新属性。
当希望使用自定义元类时,可以使用DeclarativeBaseNoMeta
基类。
2.0 版本中的新功能。
成员
mapper, mapper_args, table, table_args, tablename, metadata, registry
类签名
类sqlalchemy.orm.DeclarativeBaseNoMeta
(sqlalchemy.inspection.Inspectable
)
attribute __mapper__: ClassVar[Mapper[Any]]
将特定类映射到的Mapper
对象。
也可以使用inspect()
获得,例如inspect(klass)
。
attribute __mapper_args__: Any
将传递给Mapper
构造函数的参数字典。
另请参阅
使用声明式的 Mapper 配置选项
attribute __table__: FromClause | None
将特定子类映射到的FromClause
。
这通常是Table
的实例,但根据类的映射方式,也可能引用其他类型的FromClause
,例如Subquery
。
另请参阅
访问表和元数据
attribute __table_args__: Any
将传递给Table
构造函数的参数字典或元组。有关此集合特定结构的背景,请参阅声明式表配置。
另请参阅
声明式表配置
attribute __tablename__: Any
分配给生成的Table
对象的字符串名称,如果未直接通过DeclarativeBase.__table__
指定。
另请参阅
具有 mapped_column()的声明式表
attribute metadata: ClassVar[MetaData]
指的是将用于新Table
对象的MetaData
集合。
另请参阅
访问表和元数据
attribute registry: ClassVar[registry]
指的是新的Mapper
对象将与之关联的正在使用的registry
。
function sqlalchemy.orm.has_inherited_table(cls: Type[_O]) → bool
给定一个类,如果它继承的任何类都有一个映射表,则返回 True,否则返回 False。
这在声明式混合中用于构建在继承层次结构中的基类和子类之间行为不同的属性。
另请参阅
使用混合和基类进行映射继承模式
function sqlalchemy.orm.synonym_for(name: str, map_column: bool = False) → Callable[[Callable[[...], Any]], Synonym[Any]]
在与 Python 描述符一起生成synonym()
属性的装饰器。
被装饰的函数将被传递给synonym()
作为synonym.descriptor
参数:
class MyClass(Base): __tablename__ = 'my_table' id = Column(Integer, primary_key=True) _job_status = Column("job_status", String(50)) @synonym_for("job_status") @property def job_status(self): return "Status: %s" % self._job_status
SQLAlchemy 的混合属性功能通常比同义词更受青睐,后者是一个更传统的功能。
另请参阅
同义词 - 同义词概述
synonym()
- 映射器级函数
使用描述符和混合属性 - Hybrid Attribute 扩展提供了一种更新的方法来更灵活地增强属性行为,比使用同义词更容易实现。
function sqlalchemy.orm.object_mapper(instance: _T) → Mapper[_T]
给定一个对象,返回与该对象实例关联的主要映射器。
如果没有配置映射,则引发sqlalchemy.orm.exc.UnmappedInstanceError
。
此功能可通过检查系统使用:
inspect(instance).mapper
如果实例不是映射的一部分,则使用检查系统将引发sqlalchemy.exc.NoInspectionAvailable
。
function sqlalchemy.orm.class_mapper(class_: Type[_O], configure: bool = True) → Mapper[_O]
给定一个类,返回与该键关联的主要Mapper
。
如果给定类上没有配置映射,则引发UnmappedClassError
,或者如果传递了非类对象,则引发ArgumentError
。
相当的功能可以通过inspect()
函数实现:
inspect(some_mapped_class)
如果类未映射,则使用检查系统将引发sqlalchemy.exc.NoInspectionAvailable
。
function sqlalchemy.orm.configure_mappers() → None
初始化到目前为止在所有registry
集合中已构建的所有映射器的互映关系。
配置步骤用于协调和初始化映射类之间的relationship()
链接,以及调用配置事件,如MapperEvents.before_configured()
和MapperEvents.after_configured()
,这些事件可能被 ORM 扩展或用户定义的扩展钩子使用。
映射器配置通常是自动调用的,第一次使用特定 registry
的映射时,以及每当使用映射并且已经构造了额外的尚未配置的映射器时。然而,自动配置过程仅局限于涉及目标映射器和任何相关的 registry
对象的 registry
;这相当于在特定 registry
上调用 registry.configure()
方法。
与之相比,configure_mappers()
函数将在内存中存在的所有 registry
对象上调用配置过程,并且可能对使用许多个体 registry
对象但彼此相关的场景有用。
从版本 1.4 开始更改:从 SQLAlchemy 1.4.0b2 开始,此函数按照每个 registry
的方式工作,定位所有存在的 registry
对象并调用每个对象上的 registry.configure()
方法。可能更喜欢使用 registry.configure()
方法来限制映射器的配置仅限于特定 registry
和/或声明性基类。
自动配置被调用的点包括当映射类被实例化为实例时,以及当使用 Session.query()
或 Session.execute()
发出 ORM 查询时使用 ORM 启用的语句。
映射器配置过程,无论是由 configure_mappers()
还是 registry.configure()
调用,都提供了几个可用于增强映射器配置步骤的事件挂钩。这些挂钩包括:
MapperEvents.before_configured()
- 在configure_mappers()
或registry.configure()
执行任何工作之前调用一次;这可用于在操作继续之前建立其他选项、属性或相关映射。MapperEvents.mapper_configured()
- 在进程中配置每个单独的Mapper
时调用;将包括除其他映射器设置的反向引用之外的所有映射器状态,这些映射器尚未配置。MapperEvents.after_configured()
- 在configure_mappers()
或registry.configure()
完成后调用一次;在此阶段,所有配置操作范围内的Mapper
对象将被完全配置。请注意,调用应用程序可能仍然有其他尚未生成的映射,例如,如果它们在尚未导入的模块中,还可能有映射尚未配置,如果它们位于当前配置范围之外的其他registry
集合中。
function sqlalchemy.orm.clear_mappers() → None
删除所有类的所有映射器。
从版本 1.4 开始变更:这个函数现在定位所有的registry
对象,并调用每个对象的 registry.dispose()
方法。
这个函数从类中删除所有的仪器,并处置它们的关联映射器。一旦调用,这些类将被取消映射,以后可以用新的映射器重新映射。
clear_mappers()
不是正常使用,因为在非常特定的测试场景之外,它实际上没有任何有效用途。通常,映射器是用户定义类的永久结构组件,绝不会独立于其类被丢弃。如果映射类本身被垃圾回收,其映射器也将被自动处理。因此,clear_mappers()
仅用于在测试套件中重复使用相同类的不同映射的情况下,这本身是一个极为罕见的用例 - 唯一的这种用例实际上是 SQLAlchemy 自己的测试套件,可能是其他 ORM 扩展库的测试套件,这些库打算在一组固定的类上测试各种映射构造的组合。
function sqlalchemy.orm.util.identity_key(class_: Type[_T] | None = None, ident: Any | Tuple[Any, ...] = None, *, instance: _T | None = None, row: Row[Any] | RowMapping | None = None, identity_token: Any | None = None) → _IdentityKeyType[_T]
生成“标识键”元组,用作 Session.identity_map
字典中的键。
此函数有几种调用样式:
identity_key(class, ident, identity_token=token)
此形式接收一个映射类和一个主键标量或元组作为参数。
例如:
>>> identity_key(MyClass, (1, 2)) (<class '__main__.MyClass'>, (1, 2), None)
- 参数类:
映射类(必须是一个位置参数)
参数 ident:
主键,可以是标量或元组参数。
参数 identity_token:
可选的标识令牌
版本 1.2 中的新功能:添加了 identity_token identity_key(instance=instance)
此形式将为给定实例生成标识键。实例不必是持久的,只需其主键属性被填充(否则键将包含这些缺失值的None
)。
例如:
>>> instance = MyClass(1, 2) >>> identity_key(instance=instance) (<class '__main__.MyClass'>, (1, 2), None)
- 在此形式中,给定实例最终将通过
Mapper.identity_key_from_instance()
运行,如果对象已过期,则将执行相应行的数据库检查。
参数实例:
对象实例(必须作为关键字参数给出) identity_key(class, row=row, identity_token=token)
此形式类似于类/元组形式,但是传递了数据库结果行作为Row
或RowMapping
对象。
例如:
>>> row = engine.execute(\ text("select * from table where a=1 and b=2")\ ).first() >>> identity_key(MyClass, row=row) (<class '__main__.MyClass'>, (1, 2), None)
- 参数类:
映射类(必须是一个位置参数)
参数行:Row
由CursorResult
返回的行(必须作为关键字参数给出)
参数 identity_token:
可选的标识令牌
版本 1.2 中的新功能:添加了 identity_token
function sqlalchemy.orm.polymorphic_union(table_map, typecolname, aliasname='p_union', cast_nulls=True)
创建一个多态映射器使用的 UNION
语句。
请参见具体表继承以了解如何使用此功能。
参数:
table_map
– 将多态标识映射到Table
对象。typecolname
– “鉴别器”列的字符串名称,该列将从查询中派生,为每一行产生多态标识。如果为None
,则不生成多态鉴别器。aliasname
– 生成的alias()
构造的名称。cast_nulls
– 如果为 True,则不存在的列,表示为标记的 NULL 值,将被传递到 CAST 中。这是一种问题的传统行为,对于某些后端(如 Oracle)存在问题 - 在这种情况下,可以将其设置为 False。
function sqlalchemy.orm.orm_insert_sentinel(name: str | None = None, type_: _TypeEngineArgument[Any] | None = None, *, default: Any | None = None, omit_from_statements: bool = True) → MappedColumn[Any]
提供了一个虚拟的 mapped_column()
,它生成所谓的 sentinel 列,允许对于不具有合格的主键配置的表进行具有确定性的 RETURNING 排序的高效批量插入。
使用orm_insert_sentinel()
类似于在 Core Table
构造中使用insert_sentinel()
构造的用法。
将此构造添加到声明式映射类的指南与insert_sentinel()
构造的相同;数据库表本身也需要具有此名称的列。
关于此对象的使用背景,请参阅 配置 Sentinel 列 作为 “INSERT 语句的“插入多个值”行为 部分的一部分。
另请参见
insert_sentinel()
“INSERT 语句的“插入多个值”行为
配置 Sentinel 列
2.0.10 版本中的新增内容。
function sqlalchemy.orm.reconstructor(fn)
将一个方法装饰为‘reconstructor’挂钩。
将单个方法指定为“reconstructor”,一个类似于__init__
方法的方法,ORM 在实例从数据库中加载或者以其他方式重新构建后会调用该方法。
提示
reconstructor()
装饰器使用了 InstanceEvents.load()
事件挂钩,该事件可以直接使用。
重构器将在没有参数的情况下被调用。实例的标量(非集合)数据库映射属性将在函数内可用。急切加载的集合通常尚不可用,并且通常只包含第一个元素。在这个阶段对对象进行的 ORM 状态更改不会被记录到下一个 flush()操作中,因此重构器内的活动应该保守。
另请参阅
InstanceEvents.load()
class sqlalchemy.orm.Mapper
定义了 Python 类与数据库表或其他关系结构之间的关联,以便对该类进行 ORM 操作。
Mapper
对象是使用registry
对象上存在的映射方法实例化的。有关实例化新Mapper
对象的信息,请参阅 ORM 映射类概述。
成员
init(), add_properties(), add_property(), all_orm_descriptors, attrs, base_mapper, c, cascade_iterator(), class_, class_manager, column_attrs, columns, common_parent(), composites, concrete, configured, entity, get_property(), get_property_by_column(), identity_key_from_instance(), identity_key_from_primary_key(), identity_key_from_row(), inherits, is_mapper, is_sibling(), isa(), iterate_properties, local_table, mapped_table, mapper, non_primary, persist_selectable, polymorphic_identity, polymorphic_iterator(), polymorphic_map, polymorphic_on, primary_key, primary_key_from_instance(), primary_mapper(), relationships, selectable, self_and_descendants, single, synonyms, tables, validators, with_polymorphic_mappers
类签名
类 sqlalchemy.orm.Mapper
(sqlalchemy.orm.ORMFromClauseRole
,sqlalchemy.orm.ORMEntityColumnsClauseRole
,sqlalchemy.sql.cache_key.MemoizedHasCacheKey
,sqlalchemy.orm.base.InspectionAttr
,sqlalchemy.log.Identified
,sqlalchemy.inspection.Inspectable
,sqlalchemy.event.registry.EventTarget
,typing.Generic
)
method __init__(class_: Type[_O], local_table: FromClause | None = None, properties: Mapping[str, MapperProperty[Any]] | None = None, primary_key: Iterable[_ORMColumnExprArgument[Any]] | None = None, non_primary: bool = False, inherits: Mapper[Any] | Type[Any] | None = None, inherit_condition: _ColumnExpressionArgument[bool] | None = None, inherit_foreign_keys: Sequence[_ORMColumnExprArgument[Any]] | None = None, always_refresh: bool = False, version_id_col: _ORMColumnExprArgument[Any] | None = None, version_id_generator: Literal[False] | Callable[[Any], Any] | None = None, polymorphic_on: _ORMColumnExprArgument[Any] | str | MapperProperty[Any] | None = None, _polymorphic_map: Dict[Any, Mapper[Any]] | None = None, polymorphic_identity: Any | None = None, concrete: bool = False, with_polymorphic: _WithPolymorphicArg | None = None, polymorphic_abstract: bool = False, polymorphic_load: Literal['selectin', 'inline'] | None = None, allow_partial_pks: bool = True, batch: bool = True, column_prefix: str | None = None, include_properties: Sequence[str] | None = None, exclude_properties: Sequence[str] | None = None, passive_updates: bool = True, passive_deletes: bool = False, confirm_deleted_rows: bool = True, eager_defaults: Literal[True, False, 'auto'] = 'auto', legacy_is_orphan: bool = False, _compiled_cache_size: int = 100)
一个新的 Mapper
对象的直接构造函数。
不直接调用 Mapper
构造函数,通常通过使用 registry
对象通过声明式或命令式映射样式调用。
在 2.0 版本中进行了更改:公开的 mapper()
函数已移除;对于传统的映射配置,请使用 registry.map_imperatively()
方法。
下面记录的参数可以传递给 registry.map_imperatively()
方法,或者可以在具有声明性的 Mapper 配置选项中描述的 __mapper_args__
声明类属性中传递。
SqlAlchemy 2.0 中文文档(十)(5)https://developer.aliyun.com/article/1562919