访问者和遍历实用工具

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

注意

sqlalchemy.sql.visitors 模块是一个内部 API,并非完全公开。它可能会发生更改,并且对于 SQLAlchemy 自身内部未考虑的使用模式,可能无法按预期运行。

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 类以两种方式使用。一种是它可以充当实现该类各种 visit 方法的对象的超类。另一种是 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 的附加信息字典,用于修改其角色。在比较或缓存对象时应包含它,但是生成此键的成本相对较高。访问者应首先检查 “_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 表示的序列。

属性 sqlalchemy.sql.visitors.InternalTraversal.dp_propagate_attrs = 'PA'

访问 propagate attrs 字典。这目前硬编码为我们关心的特定元素。

属性 sqlalchemy.sql.visitors.InternalTraversal.dp_statement_hint_list = 'SH'

访问 _statement_hints Select 对象的集合。

属性 sqlalchemy.sql.visitors.InternalTraversal.dp_string = 'S'

访问纯字符串值。

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

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

属性 sqlalchemy.sql.visitors.InternalTraversal.dp_string_clauseelement_dict = 'CD'

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

属性 sqlalchemy.sql.visitors.InternalTraversal.dp_string_list = 'SL'

访问字符串列表。

属性 sqlalchemy.sql.visitors.InternalTraversal.dp_string_multi_dict = 'MD'

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

属性 sqlalchemy.sql.visitors.InternalTraversal.dp_table_hint_list = 'TH'

访问 Select 对象的 _hints 集合。

属性 sqlalchemy.sql.visitors.InternalTraversal.dp_type = 'T'

访问 TypeEngine 对象

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

属性 sqlalchemy.sql.visitors.InternalTraversal.dp_unknown_structure = 'UK'

访问未知结构。

sqlalchemy.sql.visitors.Visitable

可访问对象的基类。

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

在版本 2.0 中变更:Visitable 类在 1.4 系列中被命名为 Traversible;在 2.0 中,名称改回为 Visitable,这是 1.4 之前的名称。

在 1.4 和 2.0 版本中,这两个名称仍然可以导入。

属性 sqlalchemy.sql.visitors..sqlalchemy.sql.visitors.anon_map

cache_anon_map 的别名

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

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

遍历用法与 traverse() 相同。 visitors 字典中存在的访问器函数也可以在遍历进行时修改给定结构的内部结构。

cloned_traverse() 函数向访问方法提供属于 Immutable 接口的对象(这主要包括 ColumnClauseColumnTableClauseTable 对象)。由于此遍历仅旨在允许对象的就地修改,因此会跳过 Immutable 对象。 Immutable._clone() 方法仍然在每个对象上调用,以允许对象基于其子内部结构的克隆来替换自身(例如,ColumnClause 克隆其子查询以返回新的 ColumnClause)。

在版本 2.0 中变更:cloned_traverse() 函数省略了属于 Immutable 接口的对象。

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

函数 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 – 迭代选项字典。在现代用法中,此字典通常为空。

函数 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 子句替换 FROM 子句,这在 ORM 中是常见的用例。

函数 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__,并以可调用函数作为值,每个值表示该类型对象的访问器函数。

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

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

traverse_using() 通常在内部作为 traverse() 函数的结果被调用。

参数:

另请参阅

traverse()