在具有Indexable类型的列上定义具有“索引”属性的ORM映射类上的属性。
“index”表示该属性与具有预定义索引的Indexable列的元素相关联以访问它。Indexable类型包括ARRAY,JSON和HSTORE等类型。
The indexable extension provides Column-like interface for any element of an Indexable typed column. 在简单的情况下,它可以被视为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'这些属性也可以在课堂上进行访问。下面,我们举例说明用于生成索引SQL标准的Person.name:
>>> 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)sindex_property includes special behaviors for when the indexed data structure does not exist, and a set operation is called:
index_property,默认数据结构将是None值的Python列表,至少与索引值一样长;该值将被设置在列表中的位置。这意味着对于索引值为零的列表,在设置给定值之前,列表将初始化为[None],对于索引值5,列表将初始化为设置前设为[无, 无, 无, 无, 无]给定值的第五个元素。请注意,现有的列表不是扩展到位以接收值。index_property,Python字典将用作默认数据结构。index_property.datatype参数将默认数据结构设置为可调用的任何Python,覆盖以前的规则。index_property can be subclassed, in particular for the common use case of providing coercion of values or SQL expressions as they are accessed. 下面是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特定版本的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)ssqlalchemy.ext.indexable.index_property(attr_name, index, datatype=None, mutable=True, onebased=True)¶基础:sqlalchemy.ext.hybrid.hybrid_property
属性生成器。生成的属性描述对应于Indexable列的对象属性。
版本1.1中的新功能
__init__(attr_name, index, datatype=None, mutable=True, onebased=True)¶创建一个新的index_property。
| 参数: |
|
|---|