SQLAlchemy 2.0 文档
可索引¶
在 ORM 映射类上定义属性,这些属性针对具有 Indexable 类型的列具有 “index” 属性。
“index” 指的是属性与 Indexable 列的元素关联,并使用预定义的索引来访问它。Indexable 类型包括 ARRAY、JSON 和 HSTORE 等类型。
indexable 扩展为 Indexable 类型列的任何元素提供类似 Column 的接口。在简单情况下,它可以被视为 Column - 映射属性。
概要¶
假设 Person 是一个模型,具有主键和 JSON 数据字段。虽然此字段可能包含任意数量的编码元素,但我们希望将名为 name 的元素单独引用为一个专用属性,其行为类似于独立的列
from sqlalchemy import Column, JSON, Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.indexable import index_property
Base = declarative_base()
class Person(Base):
__tablename__ = "person"
id = Column(Integer, primary_key=True)
data = Column(JSON)
name = index_property("data", "name")如上所示,name 属性现在的行为类似于映射列。我们可以创建一个新的 Person 并设置 name 的值
>>> person = Person(name="Alchemist")现在可以访问该值
>>> person.name
'Alchemist'在幕后,JSON 字段被初始化为一个新的空白字典,并且该字段被设置
>>> person.data
{'name': 'Alchemist'}该字段是可就地修改的
>>> person.name = "Renamed"
>>> person.name
'Renamed'
>>> person.data
{'name': 'Renamed'}当使用 index_property 时,我们对可索引结构所做的更改也会自动作为历史记录进行跟踪;我们不再需要使用 MutableDict 来跟踪工作单元的此更改。
删除也正常工作
>>> del person.name
>>> person.data
{}如上所示,删除 person.name 会从字典中删除值,但不会删除字典本身。
缺少键将产生 AttributeError
>>> person = Person()
>>> person.name
AttributeError: 'name'除非您设置默认值
>>> class Person(Base):
... __tablename__ = "person"
...
... id = Column(Integer, primary_key=True)
... data = Column(JSON)
...
... name = index_property("data", "name", default=None) # See default
>>> person = Person()
>>> print(person.name)
None这些属性也可以在类级别访问。下面,我们演示了 Person.name 用于生成索引的 SQL 条件
>>> from sqlalchemy.orm import Session
>>> session = Session()
>>> query = session.query(Person).filter(Person.name == "Alchemist")上面的查询等效于
>>> query = session.query(Person).filter(Person.data["name"] == "Alchemist")可以链式调用多个 index_property 对象以产生多级索引
from sqlalchemy import Column, JSON, Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.indexable import index_property
Base = declarative_base()
class Person(Base):
__tablename__ = "person"
id = Column(Integer, primary_key=True)
data = Column(JSON)
birthday = index_property("data", "birthday")
year = index_property("birthday", "year")
month = index_property("birthday", "month")
day = index_property("birthday", "day")如上所示,一个查询例如
q = session.query(Person).filter(Person.year == "1980")在 PostgreSQL 后端,上述查询将渲染为
SELECT person.id, person.data
FROM person
WHERE person.data -> %(data_1)s -> %(param_1)s = %(param_2)s默认值¶
index_property 包括在索引数据结构不存在且调用 set 操作时的特殊行为
对于给定整数索引值的
index_property,默认数据结构将是None值的 Python 列表,至少与索引值一样长;然后将该值设置在其在列表中的位置。这意味着对于索引值零,列表将在设置给定值之前初始化为[None],对于索引值五,列表将在将第五个元素设置为给定值之前初始化为[None, None, None, None, None]。请注意,现有列表不会就地扩展以接收值。对于给定任何其他类型索引值(例如,通常是字符串)的
index_property,Python 字典用作默认数据结构。可以使用
index_property.datatype参数将默认数据结构设置为任何 Python 可调用对象,从而覆盖之前的规则。
子类化¶
index_property 可以被子类化,特别是对于在访问值或 SQL 表达式时提供强制转换的常见用例。下面是一个常见的配方,用于 PostgreSQL JSON 类型,我们希望包括自动转换和 astext()
class pg_json_property(index_property):
def __init__(self, attr_name, index, cast_type):
super(pg_json_property, self).__init__(attr_name, index)
self.cast_type = cast_type
def expr(self, model):
expr = super(pg_json_property, self).expr(model)
return expr.astext.cast(self.cast_type)上面的子类可以与 JSON 的 PostgreSQL 特定版本一起使用
from sqlalchemy import Column, Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.dialects.postgresql import JSON
Base = declarative_base()
class Person(Base):
__tablename__ = "person"
id = Column(Integer, primary_key=True)
data = Column(JSON)
age = pg_json_property("data", "age", Integer)实例级别的 age 属性的工作方式与以前相同;但是,在渲染 SQL 时,PostgreSQL 的 ->> 运算符将用于索引访问,而不是通常的索引运算符 ->
>>> query = session.query(Person).filter(Person.age < 20)上面的查询将渲染为: .. sourcecode:: sql
SELECT person.id, person.data FROM person WHERE CAST(person.data ->> %(data_1)s AS INTEGER) < %(param_1)s
API 参考¶
| 对象名称 | 描述 |
|---|---|
属性生成器。生成的属性描述了对应于 |
- class sqlalchemy.ext.indexable.index_property¶
属性生成器。生成的属性描述了对应于
Indexable列的对象属性。成员
-
method
sqlalchemy.ext.indexable.index_property.__init__(attr_name, index, default=<object object>, datatype=None, mutable=True, onebased=True)¶ 创建一个新的
index_property。- 参数:
attr_name¶ – Indexable 类型列的属性名称,或返回可索引结构的其他属性。
index¶ – 用于获取和设置此值的索引。这应该是整数的 Python 端索引值。
default¶ – 当给定索引处没有值时,将返回此值而不是 AttributeError。
datatype¶ – 当字段为空时使用的默认数据类型。默认情况下,这从使用的索引类型派生;整数索引的 Python 列表,或任何其他索引样式的 Python 字典。对于列表,列表将被初始化为至少
index个元素的 None 值列表。mutable¶ – 如果为 False,则不允许对属性进行写入和删除操作。
onebased¶ – 假设此值的 SQL 表示形式是基于 1 的;也就是说,SQL 中的第一个索引是 1,而不是零。
-
method
flambé! 龙和 The Alchemist 图像设计由 Rotem Yaari 创作并慷慨捐赠。
使用 Sphinx 7.2.6 创建。文档上次生成时间:2025年3月11日星期二下午 02:40:17 EDT