SqlAlchemy 2.0 中文文档(十)(4)

简介: SqlAlchemy 2.0 中文文档(十)

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)
    此形式类似于类/元组形式,但是传递了数据库结果行作为 RowRowMapping 对象。
    例如:
>>> 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)
  • 参数类:
    映射类(必须是一个位置参数)
    参数行:
    RowCursorResult 返回的行(必须作为关键字参数给出)
    参数 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.ORMFromClauseRolesqlalchemy.orm.ORMEntityColumnsClauseRolesqlalchemy.sql.cache_key.MemoizedHasCacheKeysqlalchemy.orm.base.InspectionAttrsqlalchemy.log.Identifiedsqlalchemy.inspection.Inspectablesqlalchemy.event.registry.EventTargettyping.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

相关文章
|
4月前
|
SQL JSON 关系型数据库
SqlAlchemy 2.0 中文文档(五)(5)
SqlAlchemy 2.0 中文文档(五)
52 4
|
4月前
|
存储 SQL API
SqlAlchemy 2.0 中文文档(四)(5)
SqlAlchemy 2.0 中文文档(四)
33 3
|
4月前
|
SQL 测试技术 Python
SqlAlchemy 2.0 中文文档(四)(4)
SqlAlchemy 2.0 中文文档(四)
54 3
|
4月前
|
SQL 存储 数据库
SqlAlchemy 2.0 中文文档(一)(4)
SqlAlchemy 2.0 中文文档(一)
68 1
|
4月前
|
SQL 缓存 关系型数据库
SqlAlchemy 2.0 中文文档(三)(2)
SqlAlchemy 2.0 中文文档(三)
33 1
|
4月前
|
SQL 数据库 Python
SqlAlchemy 2.0 中文文档(十)(3)
SqlAlchemy 2.0 中文文档(十)
35 1
|
4月前
|
SQL JSON 关系型数据库
SqlAlchemy 2.0 中文文档(二)(4)
SqlAlchemy 2.0 中文文档(二)
42 2
|
4月前
|
SQL 自然语言处理 数据库
SqlAlchemy 2.0 中文文档(二)(3)
SqlAlchemy 2.0 中文文档(二)
46 2
|
4月前
|
存储 Python
SqlAlchemy 2.0 中文文档(七)(5)
SqlAlchemy 2.0 中文文档(七)
26 1
|
4月前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(十)(2)
SqlAlchemy 2.0 中文文档(十)
25 0