用于 Python 的 Redis 对象映射器
项目描述
Rom - Python 的 Redis 对象映射器
版权所有 2013-2021 乔赛亚·卡尔森
在 LGPL 许可证版本 2.1 和版本 3 下发布(您可以选择要绑定的版本)。
提供赞助
不喜欢 LGPL?赞助该项目并获得几乎任何您想要的许可证。
该项目部分由 structd.com 赞助。从历史上看,rom 已被用于帮助支持 chownow.com 的数百万份食品订单的交付,并已被用作几家初创公司的主要后端和原型,这些初创公司一路走到了 A 系列。
感谢我们的赞助商和那些使用我们服务的人。
欢迎您提供良好的服务。
您的公司链接在这里。
文档
可以找到更新的文档:https ://josiahcarlson.github.io/rom/
什么
Rom 是一个包,其目的是在 Python 的 Redis 中提供活动记录样式的数据建模,类似于 Django ORM、SQLAlchemy、Google 的 Appengine 数据存储等的语义。
为什么
我正在构建一个个人项目,想使用 Redis 来存储我的一些数据,但不想糟糕地破解它。我查看了 Python 中可用的现有 Redis 对象映射器,但不喜欢提供的特性和功能。
有什么可用的
数据类型:
字符串(2.x:str/unicode,3.3+:str)、整数、浮点数、小数、布尔值
日期时间.日期时间,日期时间.日期,日期时间.时间
Json 列(用于嵌套结构)
OneToMany 和 ManyToOne 列(用于模型参考)
非rom ForeignModel 参考支持
索引:
数值范围获取、搜索和排序
全字文本搜索(查找带有 col X 的单词 A 和 B 的条目)
前缀匹配(可用于基于前缀的自动完成)
后缀匹配(可用于基于后缀的自动完成)
基于字符串的列的模式匹配
使用 Redis 2.6.0 及更高版本时,除地理索引之外的所有索引均可用
Redis 3.2.0 及更高版本提供地理索引
其它功能:
每线程实体缓存(尽量减少往返,轻松保存所有实体)
缓存查询结果并获取任何其他用途的密钥的能力(请参阅: Query.cached_result())
入门
确保已安装 Python 2.6、2.7 或 3.3+
确保您安装了 Andy McCurdy 的 Redis 客户端库: https ://github.com/andymccurdy/redis-py/或 https://pypi.python.org/pypi/redis
确保您已安装 Python 2 和 3 兼容库“六”:https ://pypi.python.org/pypi/six
(可选)确保为 Python 安装了hiredis 库
确保您已安装 Redis 服务器并可远程使用
通过 rom.util.set_connection_settings()更新rom的 Redis 连接设置(其他连接更新选项,包括每个模型的连接,可以在rom.util 文档中阅读):
import redis from rom import util util.set_connection_settings(host='myhost', db=7)
创建模型:
import rom # All models to be handled by rom must derived from rom.Model class User(rom.Model): email = rom.String(required=True, unique=True, suffix=True) salt = rom.String() hash = rom.String() created_at = rom.Float(default=time.time)创建模型实例并保存:
PASSES = 32768 def gen_hash(password, salt=None): salt = salt or os.urandom(16) comp = salt + password out = sha256(comp).digest() for i in xrange(PASSES-1): out = sha256(out + comp).digest() return salt, out user = User(email='user@host.com') user.salt, user.hash = gen_hash(password) user.save() # session.commit() or session.flush() works too稍后加载并使用该对象:
user = User.get_by(email='user@host.com') at_gmail = User.query.endswith(email='@gmail.com').all()
Lua 支持
从 0.25.0 及更高版本开始,rom 假定您使用的是 Redis 2.6 或更高版本,它支持服务器端 Lua 脚本。这允许支持多个唯一列约束,而无需烦人的竞争条件和重试。这也允许在某些列类型上支持前缀、后缀和模式匹配。
如果您使用的是 2.6 之前的 Redis 版本,则应升级 Redis。如果您无法或不愿意升级 Redis,但仍希望使用 rom,则应调用rom._disable_lua_writes(),这将阻止您使用需要 Lua 脚本支持的功能。
即将到期的模型/TTL
有一系列功能请求/错误报告/拉取请求以添加 rom 自动删除和/或过期存储在 Redis 中的实体数据的能力。这是一个已提出(截至 2016 年 1 月)6 次不同的请求。
长话短说:rom 将一堆数据存储在二级结构中以加快查询速度。当模型“过期”时,该数据不会被删除。要删除该数据,您必须运行一个清理功能,该功能必须扫描每个实体以确定模型是否已过期。这是一个巨大的浪费,是好的设计的对立面。
相反,如果您使用index=True创建一个新的expire_at浮点列,则该列可以存储实体何时到期。然后要使数据过期,您可以使用:Model.query.filter(expire_at=(0, time.time())).limit(10)来(例如)获取最多 10 个需要过期的最旧实体.
现在,我知道你在想什么。你在想,“但我希望数据会自行消失。” 我不反对。但要做到这一点,Redis 需要增加 Lua 脚本触发器,或者您需要运行一个单独的守护进程来定期清理剩余数据。但是……如果你需要运行一个单独的守护进程来通过扫描你所有的 rom 实体来清理剩余的数据,那么保持一个明确的列并有效地完成它不是更好/更快吗?我想是的,你也应该如此。