可转位的
在ORM映射类上定义属性,这些类对具有 Indexable
类型。
“索引”是指属性与 Indexable
带有预定义索引的列以访问它。这个 Indexable
类型包括类型,例如 ARRAY
, JSON
和 HSTORE
.
这个 indexable
扩展提供 Column
-类似于任何元素的接口 Indexable
类型化列。在简单的情况下,它可以被视为 Column
-映射的属性。
1.1 新版功能.
简介
鉴于 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
包括索引数据结构不存在时的特殊行为,并调用集合操作:
对于一个
index_property
如果给定一个整数索引值,则默认的数据结构将是None
值,至少与索引值一样长;然后在列表中的位置设置该值。这意味着对于索引值为零,列表将初始化为[None]
在设置给定值之前,如果索引值为5,则列表将初始化为[None, None, None, None, None]
在将第五个元素设置为给定值之前。请注意,现有列表是 not 扩展到位以接收值。对于一个
index_property
如果给定任何其他类型的索引值(例如,通常是字符串),则使用Python字典作为默认数据结构。默认数据结构可以设置为使用
index_property.datatype
参数,重写以前的规则。
子类别化
index_property
可以是子类的,特别是对于在访问值或SQL表达式时提供强制值或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)
上述子类可与PostgreSQL特定版本的 JSON
::
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)
以上查询将呈现:
SELECT person.id, person.data FROM person WHERE CAST(person.data ->> %(data_1)s AS INTEGER) < %(param_1)s
API引用
Object Name | Description |
---|---|
属性生成器。生成的属性描述与 |
- class sqlalchemy.ext.indexable.index_property(attr_name, index, default=<object object>, datatype=None, mutable=True, onebased=True)¶
属性生成器。生成的属性描述与
Indexable
列。1.1 新版功能.
参见
类签名
class
sqlalchemy.ext.indexable.index_property
(sqlalchemy.ext.hybrid.hybrid_property
)- 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-side索引值。
default¶ -- 将返回的值,而不是 AttributeError 当给定索引处没有值时。
datatype¶ -- 字段为空时使用的默认数据类型。默认情况下,这是从使用的索引类型派生的;整数索引的python列表,或任何其他类型索引的python字典。对于列表,该列表将初始化为一个至少为
index
元素长。mutable¶ -- 如果为false,则不允许对属性进行写入和删除。
onebased¶ -- 假设此值的SQL表示形式是基于一个;即,SQL中的第一个索引是1,而不是零。
- method