文章目录
- 13.10 字段
- class CompressedField
- class PickleField
- 13.11 混合属性 Hybrid Attributes
- 13.11.1 混合 API
- class hybrid_method
- class hybrid_property
- 13.12 键/值存储 Key/Value Store
- class KeyValue
13.10 字段
这些字段可以在playhouse.fields模块中找到。
class CompressedField
class CompressedField([compression_level=6[, algorithm='zlib'[, **kwargs]]])
参数:
- compression_level ( int ) – 0 到 9 之间的值。
- algorithm( str ) – 要么’zlib’要么’bz2’。
使用指定算法存储压缩数据。该字段扩展 BlobField,透明地存储数据库中数据的压缩表示。
class PickleField
class PickleField
通过透明地酸洗和取消酸洗存储在字段中的数据来存储任意 Python 数据。该字段扩展BlobField. 如果该 cPickle模块可用,它将被使用。
13.11 混合属性 Hybrid Attributes
混合属性封装了在 Python 和SQL 级别运行的功能。混合属性的想法来自 SQLAlchemy 中的同名功能。考虑以下示例:
class Interval(Model):start = IntegerField()end = IntegerField()@hybrid_propertydef length(self):return self.end - self.start@hybrid_methoddef contains(self, point):return (self.start <= point) & (point < self.end)
混合属性的名称来自于length 属性的行为会根据是通过 Interval类还是Interval实例访问而有所不同。
如果通过实例访问,那么它的行为与您预期的一样。
但是,如果通过Interval.length类属性访问,则长度计算将表示为 SQL 表达式。例如:
query = Interval.select().where(Interval.length > 5)
此查询将等效于以下 SQL:
SELECT "t1"."id", "t1"."start", "t1"."end"
FROM "interval" AS t1
WHERE (("t1"."end" - "t1"."start") > 5)
该playhouse.hybrid模块还包含一个装饰器,用于实现可以接受参数的混合方法。与混合属性一样,当通过模型实例访问时,函数会按原样正常执行。但是,当在类上调用混合方法时,它将生成一个 SQL 表达式。
例子:
query = Interval.select().where(Interval.contains(2))
此查询等效于以下 SQL:
SELECT "t1"."id", "t1"."start", "t1"."end"
FROM "interval" AS t1
WHERE (("t1"."start" <= 2) AND (2 < "t1"."end"))
对于 Python 实现与 SQL 实现略有不同的情况,还有一个额外的 API。让我们为模型添加一个radius方法Interval。因为该方法计算的是绝对值,所以我们将 Pythonabs()函数用于实例部分,将fn.ABS()SQL 函数用于类部分。
class Interval(Model):start = IntegerField()end = IntegerField()@hybrid_propertydef length(self):return self.end - self.start@hybrid_propertydef radius(self):return abs(self.length) / 2@radius.expressiondef radius(cls):return fn.ABS(cls.length) / 2
巧妙的是,这两个radius实现都引用了 length混合属性!通过Interval实例访问时,半径计算将在 Python 中执行。当通过Interval 类调用时,我们将获得相应的 SQL。
例子:
query = Interval.select().where(Interval.radius < 3)
此查询等效于以下 SQL:
SELECT "t1"."id", "t1"."start", "t1"."end"
FROM "interval" AS t1
WHERE ((abs("t1"."end" - "t1"."start") / 2) < 3)
很整洁,对吧?谢谢你的好主意,SQLAlchemy!
13.11.1 混合 API
class hybrid_method
class hybrid_method(func[, expr=None])
方法装饰器,允许定义具有实例级和类级行为的 Python 对象方法。
例子:
class Interval(Model):start = IntegerField()end = IntegerField()@hybrid_methoddef contains(self, point):return (self.start <= point) & (point < self.end)
当使用Interval实例调用时,该contains方法的行为将与您预期的一样。但是,当作为类方法调用时,将生成一个 SQL 表达式:
query = Interval.select().where(Interval.contains(2))
将生成以下 SQL:
SELECT "t1"."id", "t1"."start", "t1"."end"
FROM "interval" AS t1
WHERE (("t1"."start" <= 2) AND (2 < "t1"."end"))
expression(expr)
用于指定 SQL 表达式生成方法的方法装饰器。
class hybrid_property
class hybrid_property(fget[, fset=None[, fdel=None[, expr=None]]])
允许定义具有实例级和类级行为的 Python 对象属性的方法装饰器。
例子:
class Interval(Model):start = IntegerField()end = IntegerField()@hybrid_propertydef length(self):return self.end - self.start@hybrid_propertydef radius(self):return abs(self.length) / 2@radius.expressiondef radius(cls):return fn.ABS(cls.length) / 2
在Interval实例上访问时,lengthandradius 属性的行为将与您预期的一样。但是,当作为类属性访问时,将生成一个 SQL 表达式:
query = (Interval.select().where((Interval.length > 6) &(Interval.radius >= 3)))
将生成以下 SQL:
SELECT "t1"."id", "t1"."start", "t1"."end"
FROM "interval" AS t1
WHERE ((("t1"."end" - "t1"."start") > 6) AND((abs("t1"."end" - "t1"."start") / 2) >= 3)
)
13.12 键/值存储 Key/Value Store
该playhouse.kv模块包含持久字典的实现。
class KeyValue
class KeyValue([key_field=None[, value_field=None[, ordered=False[, database=None[, table_name=‘keyvalue’]]]]])
参数:
- key_field ( Field ) – 用于键的字段。默认为 CharField. 必须有 primary_key=True。
- value_field ( Field ) – 用于值的字段。默认为 PickleField.
- ordered( bool ) – 数据应按键排序顺序返回。
- database( Database ) – 存储键/值数据的数据库。如果未指定,将使用内存中的 SQLite 数据库。
- table_name ( str ) – 数据存储的表名。
用于存储键/值数据的类字典 API。与字典一样,支持预期的 API,但还具有接受用于获取、设置和删除项目的表达式的附加功能。
KeyValue 实例化时会自动创建表(如果它不存在) 。
使用高效的 upsert 实现来设置和更新/覆盖键/值对。
基本示例:
# Create a key/value store, which uses an in-memory SQLite database
# for data storage.
KV = KeyValue()# Set (or overwrite) the value for "k1".
KV['k1'] = 'v1'# Set (or update) multiple keys at once (uses an efficient upsert).
KV.update(k2='v2', k3='v3')# Getting values works as you'd expect.
assert KV['k2'] == 'v2'# We can also do this:
for value in KV[KV.key > 'k1']:print(value)# 'v2'
# 'v3'# Update multiple values at once using expression:
KV[KV.key > 'k1'] = 'vx'# What's stored in the KV?
print(dict(KV))# {'k1': 'v1', 'k2': 'vx', 'k3': 'vx'}# Delete a single item.
del KV['k2']# How many items are stored in the KV?
print(len(KV))
# 2# Delete items that match the given condition.
del KV[KV.key > 'k1']
contains(表达式)
参数: 表达式– 单个键或表达式
返回: 布尔值是否存在键/表达式。
例子:
>>> kv = KeyValue()
>>> kv.update(k1='v1', k2='v2')>>> 'k1' in kv
True
>>> 'kx' in kv
False>>> (KV.key < 'k2') in KV
True
>>> (KV.key > 'k2') in KV
False
len()
返回: 存储的项目计数。
getitem(expr)
参数: 表达式– 单个键或表达式。
返回: 对应于键/表达式的值。
提高: KeyError如果给定单个密钥但未找到。
例子:
>>> KV = KeyValue()
>>> KV.update(k1='v1', k2='v2', k3='v3')>>> KV['k1']
'v1'
>>> KV['kx']
KeyError: "kx" not found>>> KV[KV.key > 'k1']
['v2', 'v3']
>>> KV[KV.key < 'k1']
[]
setitem(expr, value)
参数:
- expr – 单个键或表达式。
- value – 为键设置的值
设置给定键的值。如果expr是一个表达式,那么任何匹配该表达式的键都将更新它们的值。
例子:
>>> KV = KeyValue()
>>> KV.update(k1='v1', k2='v2', k3='v3')>>> KV['k1'] = 'v1-x'
>>> print(KV['k1'])
'v1-x'>>> KV[KV.key >= 'k2'] = 'v99'
>>> dict(KV)
{'k1': 'v1-x', 'k2': 'v99', 'k3': 'v99'}
delitem(expr)
参数: 表达式– 单个键或表达式。
删除给定的键。如果给出了表达式,则删除与该表达式匹配的所有键。
例子:
>>> KV = KeyValue()
>>> KV.update(k1=1, k2=2, k3=3)>>> del KV['k1'] # Deletes "k1".
>>> del KV['k1']
KeyError: "k1" does not exist>>> del KV[KV.key > 'k2'] # Deletes "k3".
>>> del KV[KV.key > 'k99'] # Nothing deleted, no keys match.
keys()
返回: 表中所有键的可迭代。
values()
返回: 表中所有值的可迭代。
items()
返回: 表中所有键/值对的可迭代对象。
update([__data=None[, **mapping]])
有效地批量插入或替换给定的键/值对。
例子:
>>> KV = KeyValue()
>>> KV.update(k1=1, k2=2) # Sets 'k1'=1, 'k2'=2.>>> dict(KV)
{'k1': 1, 'k2': 2}>>> KV.update(k2=22, k3=3) # Updates 'k2'->22, sets 'k3'=3.>>> dict(KV)
{'k1': 1, 'k2': 22, 'k3': 3}>>> KV.update({'k2': -2, 'k4': 4}) # Also can pass a dictionary.>>> dict(KV)
{'k1': 1, 'k2': -2, 'k3': 3, 'k4': 4}
get(expr[, default=None])
参数:
- expr – 单个键或表达式。
- default - 如果未找到密钥,则为默认值。
返回:
如果未找到单个键,则为给定键/表达式的值或默认值。
获取给定键的值。如果键不存在,则返回默认值,除非键是表达式,在这种情况下将返回空列表。
pop(expr[, default=Sentinel])
参数:
- expr – 单个键或表达式。
- default – 如果键不存在,则为默认值。
返回:
如果未找到单个键,则为给定键/表达式的值或默认值。
获取值并删除给定的键。如果键不存在,则返回默认值,除非键是表达式,在这种情况下返回空列表。
clear()
从键值表中删除所有项目。