访问者和遍历工具

The sqlalchemy.sql.visitors 模块包含用于遍历 Core SQL 表达式结构的类和函数。这类似于 Python 的 ast 模块,因为它提供了一个系统,让程序可以对 SQL 表达式的每个组件进行操作。常用的目的包括定位各种类型的元素,例如 TableBindParameter 对象,以及改变结构的状态,例如用其他 FROM 子句替换某些 FROM 子句。

注意

the sqlalchemy.sql.visitors 模块是一个内部 API,并非完全公开。它可能会发生变化,并且对于未在 SQLAlchemy 内部考虑的使用模式,可能无法按预期工作。

The sqlalchemy.sql.visitors 模块是 SQLAlchemy 的内部的一部分,通常不会被调用应用程序代码使用。然而,它在某些边缘情况下有用,例如构建缓存例程时以及使用 自定义 SQL 结构和编译扩展 构建自定义 SQL 表达式时。

访问者/遍历接口和库函数。

对象名称 描述

anon_map

cache_anon_map 的别名

cloned_traverse(obj, opts, visitors)

克隆给定的表达式结构,允许访问者对可变对象进行修改。

ExternalTraversal

访问者对象的基类,可以使用 traverse() 函数从外部进行遍历。

InternalTraversal

定义用于内部遍历的访问者符号。

iterate(obj[, opts])

遍历给定的表达式结构,返回一个迭代器。

replacement_traverse(obj, opts, replace)

克隆给定的表达式结构,允许通过给定的替换函数进行元素替换。

traverse(obj, opts, visitors)

使用默认迭代器遍历和访问给定的表达式结构。

traverse_using(iterator, obj, visitors)

使用给定的对象迭代器访问给定的表达式结构。

Visitable

可访问对象的基类。

class sqlalchemy.sql.visitors.ExternalTraversal

访问者对象的基类,可以使用 traverse() 函数从外部进行遍历。

通常建议直接使用 traverse() 函数。

类签名

class sqlalchemy.sql.visitors.ExternalTraversal (sqlalchemy.util.langhelpers.MemoizedSlots)

method sqlalchemy.sql.visitors.ExternalTraversal.chain(visitor: ExternalTraversal) _ExtT

将另一个 ExternalTraversal ‘链接’ 到此 ExternalTraversal 上

链接的访问者将在此访问者之后接收所有访问事件。

method sqlalchemy.sql.visitors.ExternalTraversal.iterate(obj: ExternallyTraversible | None) Iterator[ExternallyTraversible]

遍历给定的表达式结构,返回所有元素的迭代器。

method sqlalchemy.sql.visitors.ExternalTraversal.traverse(obj: ExternallyTraversible | None) ExternallyTraversible | None

遍历和访问给定的表达式结构。

attribute sqlalchemy.sql.visitors.ExternalTraversal.visitor_iterator

遍历此访问者和每个‘链接’的访问者。

class sqlalchemy.sql.visitors.InternalTraversal

定义用于内部遍历的访问者符号。

InternalTraversal 类以两种方式使用。 一种是它可以作为实现类各种访问方法的对象的超类。 另一种是 InternalTraversal 本身的符号在 _traverse_internals 集合中使用。 例如,Case 对象将 _traverse_internals 定义为

class Case(ColumnElement[_T]):
    _traverse_internals = [
        ("value", InternalTraversal.dp_clauseelement),
        ("whens", InternalTraversal.dp_clauseelement_tuples),
        ("else_", InternalTraversal.dp_clauseelement),
    ]

上面,Case 类将它的内部状态表示为名为 valuewhenselse_ 的属性。 它们分别链接到一个 InternalTraversal 方法,该方法指示每个属性所指的数据结构类型。

使用 _traverse_internals 结构,类型为 InternalTraversible 的对象将自动实现以下方法

  • HasTraverseInternals.get_children()

  • HasTraverseInternals._copy_internals()

  • HasCacheKey._gen_cache_key()

子类也可以直接实现这些方法,特别是对于 HasTraverseInternals._copy_internals() 方法,当需要特殊步骤时。

版本 1.4 中新增。

类签名

class sqlalchemy.sql.visitors.InternalTraversal (enum.Enum)

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_annotations_key = 'AK'

访问 _annotations_cache_key 元素。

这是一个关于 ClauseElement 的附加信息的字典,它修改了 ClauseElement 的角色。 在比较或缓存对象时,应该包含它,但是生成此密钥相对昂贵。 访问者应该首先检查“_annotations”字典是否为 None,然后再创建此密钥。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_anon_name = 'AN'

访问一个可能是“匿名化”的字符串值。

字符串值被认为对缓存密钥生成很重要。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_boolean = 'B'

访问一个布尔值。

布尔值被认为对缓存密钥生成很重要。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_clauseelement = 'CE'

访问一个 ClauseElement 对象。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_clauseelement_list = 'CL'

访问一个 ClauseElement 对象列表。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_clauseelement_tuple = 'CT'

访问一个 ClauseElement 对象元组。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_clauseelement_tuples = 'CTS'

访问一个包含 ClauseElement 对象的元组列表。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_dialect_options = 'DO'

访问一个方言选项结构。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_dml_multi_values = 'DML_MV'

访问 Insert 对象的 values() 多值字典列表。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_dml_ordered_values = 'DML_OV'

访问 Update 对象的 values() 有序元组列表。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_dml_values = 'DML_V'

访问 ValuesBase(例如 Insert 或 Update)对象的 values() 字典。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_fromclause_canonical_column_collection = 'FC'

columns 属性上下文中访问 FromClause 对象。

列集合是“规范”的,这意味着它是 ColumnClause 对象的原始定义位置。目前,这意味着正在访问的对象仅为 TableClauseTable 对象。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_fromclause_ordered_set = 'CO'

访问一组排序的 FromClause 对象。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_has_cache_key = 'HC'

访问 HasCacheKey 对象。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_has_cache_key_list = 'HL'

访问 HasCacheKey 对象的列表。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_has_cache_key_tuples = 'HT'

访问包含 HasCacheKey 对象的元组列表。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_ignore = 'IG'

指定应完全忽略的对象。

这目前适用于函数调用参数缓存,其中某些参数不应被视为缓存键的一部分。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_inspectable = 'IS'

访问可检查对象,其中返回值为 HasCacheKey 对象。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_inspectable_list = 'IL'

访问可检查对象的列表,这些对象在检查后是 HasCacheKey 对象。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_multi = 'M'

访问可能是 HasCacheKey 或可能是普通可散列对象的对象。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_multi_list = 'MT'

访问包含可能是 HasCacheKey 或可能是普通可散列对象的元素的元组。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_named_ddl_element = 'DD'

访问简单的命名 DDL 元素。

此方法当前使用的是 Sequence

该对象仅在用于生成缓存键时才被认为是重要的,因为它只有名称,没有其他方面。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_operator = 'O'

访问运算符。

该运算符是来自 sqlalchemy.sql.operators 模块的函数。

该运算符值被认为对缓存键生成很重要。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_plain_dict = 'PD'

访问带有字符串键的字典。

字典的键应该是字符串,值应该是不可变的并且可散列的。字典被认为对缓存键生成很重要。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_plain_obj = 'PO'

访问普通的 Python 对象。

该值应该是不可变的并且可散列的,例如整数。该值被认为对缓存键生成很重要。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_prefix_sequence = 'PS'

访问 HasPrefixesHasSuffixes 表示的序列。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_propagate_attrs = 'PA'

访问传播属性字典。 这将硬编码到我们目前关心的特定元素。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_statement_hint_list = 'SH'

访问 _statement_hints 集合 Select 对象。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_string = 'S'

访问一个普通的字符串值。

示例包括表名和列名、绑定参数键、特殊关键字,如“UNION”、“UNION ALL”。

字符串值被认为对缓存密钥生成很重要。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_string_clauseelement_dict = 'CD'

访问字符串键到 ClauseElement 对象的字典。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_string_list = 'SL'

访问字符串列表。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_string_multi_dict = 'MD'

访问字符串键到值的字典,这些值可以是普通不可变/可散列的,也可以是 HasCacheKey 对象。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_table_hint_list = 'TH'

访问 _hints 集合 Select 对象。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_type = 'T'

访问一个 TypeEngine 对象

类型对象被认为对缓存键生成很重要。

attribute sqlalchemy.sql.visitors.InternalTraversal.dp_unknown_structure = 'UK'

访问一个未知结构。

class sqlalchemy.sql.visitors.Visitable

可访问对象的基类。

Visitable 用于实现 SQL 编译器调度函数。 其他形式的遍历,如用于缓存键生成,是使用 HasTraverseInternals 接口单独实现的。

Changed in version 2.0: The Visitable 类在 1.4 系列中被称为 Traversible; 该名称在 2.0 中改为 Visitable,这是它在 1.4 之前的样子。

这两个名称在 1.4 和 2.0 版本中都可导入。

attribute sqlalchemy.sql.visitors..sqlalchemy.sql.visitors.anon_map

cache_anon_map 的别名

function sqlalchemy.sql.visitors.cloned_traverse(obj: ExternallyTraversible | None, opts: Mapping[str, Any], visitors: Mapping[str, Callable[[Any], None]]) ExternallyTraversible | None

克隆给定的表达式结构,允许访问者对可变对象进行修改。

遍历的使用方式与 traverse() 相同。 在 visitors 字典中出现的访问器函数也可以在遍历过程中修改给定结构的内部。

The cloned_traverse() function does not provide objects that are part of the Immutable interface to the visit methods (this primarily includes ColumnClause, Column, TableClause and Table objects). As this traversal is only intended to allow in-place mutation of objects, Immutable objects are skipped. The Immutable._clone() method is still called on each object to allow for objects to replace themselves with a different object based on a clone of their sub-internals (e.g. a ColumnClause that clones its subquery to return a new ColumnClause).

版本 2.0 中的变更: The cloned_traverse() 函数会忽略属于 Immutable 接口的对象。

cloned_traverse()replacement_traverse() 函数的核心 API 功能,除了用于实现迭代的 ClauseElement.get_children() 函数外,还有 ClauseElement._copy_internals() 方法。为了使 ClauseElement 结构能够正确地支持克隆和替换遍历,它需要能够将克隆函数传递到其内部成员中,以便为它们创建副本。

function sqlalchemy.sql.visitors.iterate(obj: ExternallyTraversible | None, opts: Mapping[str, Any] = {}) Iterator[ExternallyTraversible]

遍历给定的表达式结构,返回一个迭代器。

遍历被配置为广度优先。

iterate() 函数的核心 API 功能是 ClauseElement.get_children() 方法 ClauseElement 对象。该方法应该返回与特定 ClauseElement 对象关联的所有 ClauseElement 对象。例如,Case 结构将引用其“whens”和“else_”成员变量中的一系列 ColumnElement 对象。

参数:
  • obj – 要遍历的 ClauseElement 结构

  • opts – 迭代选项字典。此字典在现代用法中通常为空。

function sqlalchemy.sql.visitors.replacement_traverse(obj: ExternallyTraversible | None, opts: Mapping[str, Any], replace: _TraverseTransformCallableType[Any]) ExternallyTraversible | None

克隆给定的表达式结构,允许通过给定的替换函数进行元素替换。

此函数与 cloned_traverse() 函数非常相似,只是它没有被传递访问者字典,而是将所有元素无条件地传递给给定的 replace 函数。然后 replace 函数可以选择返回一个将替换给定对象的全新对象。如果它返回 None,则该对象将保留在原位。

cloned_traverse()replacement_traverse() 之间的使用区别在于,在前一种情况下,将一个已克隆的对象传递给访问者函数,访问者函数可以操纵对象的内部状态。在后一种情况下,访问者函数应该只返回一个完全不同的对象,或者什么也不做。

replacement_traverse() 的用例是将 SQL 结构中的 FROM 子句替换为另一个,这是 ORM 中的常见用例。

function sqlalchemy.sql.visitors.traverse(obj: ExternallyTraversible | None, opts: Mapping[str, Any], visitors: Mapping[str, Callable[[Any], None]]) ExternallyTraversible | None

使用默认迭代器遍历和访问给定的表达式结构。

例如

from sqlalchemy.sql import visitors

stmt = select(some_table).where(some_table.c.foo == 'bar')

def visit_bindparam(bind_param):
    print("found bound value: %s" % bind_param.value)

visitors.traverse(stmt, {}, {"bindparam": visit_bindparam})

对象迭代使用 iterate() 函数,该函数使用堆栈进行广度优先遍历。

参数:
  • obj – 要遍历的 ClauseElement 结构

  • opts – 迭代选项字典。此字典在现代用法中通常为空。

  • visitors – 访问函数字典。字典应以字符串作为键,每个键对应于特定类型 SQL 表达式对象的 __visit_name__,以及可调用函数作为值,每个函数代表该类型的对象的访问者函数。

function sqlalchemy.sql.visitors.traverse_using(iterator: Iterable[ExternallyTraversible], obj: ExternallyTraversible | None, visitors: Mapping[str, Callable[[Any], None]]) ExternallyTraversible | None

使用给定的对象迭代器访问给定的表达式结构。

traverse_using() 通常在 traverse() 函数的内部调用。

参数:

另请参见

traverse()