Redis OM Python是官方维护的面向对象映射库,目标是让开发者用类似Django或SQLAlchemy的方式操作Redis中的数据。它并不替代redis-py,而是在其之上封装了模型定义、索引管理和查询构造能力。底层依赖Redis的RediSearch与RedisJSON模块,因此使用前必须确认Redis服务端加载了这两个扩展。

模型定义与字段映射原理
在Redis OM Python中,所有可持久化的对象都继承自redis_om.model.Model。类属性使用Field来描述字段类型与索引选项,库会根据这些声明在Redis中创建RediSearch索引。与关系型ORM不同,这里没有表概念,每个模型对应一个索引键前缀,对象以RedisJSON或哈希形式存储,具体由model_config中的storage_type决定。
字段映射的核心在于类型注解与索引标记。例如字符串字段若需全文检索,要设置index=True且指定full_text_search=True;数值字段可标记sortable=True以支持排序。模型保存时,库会把Python对象序列化为JSON文档,并将索引字段同步到RediSearch。如果字段类型声明错误,运行期不会立刻报错,但查询时会出现空结果,因此定义阶段就要核对类型。
下面的示例展示了一个用户模型,包含主键、姓名、年龄和注册时间。注意PrimaryKey用于声明业务主键,否则库会生成默认ULID。
from redis_om import Model, Field, PrimaryKey
from typing import Optional
from datetime import datetime
class User(Model):
model_config = {"storage_type": "json"}
uid: str = PrimaryKey()
name: str = Field(index=True, full_text_search=True)
age: int = Field(index=True, sortable=True)
created_at: datetime = Field(default_factory=datetime.now)
user = User(uid="u1001", name="张三", age=28)
user.save()
表达式查询与索引编译机制
Redis OM Python的查询语法借鉴了Django ORM,通过模型的find方法返回查询集。它把Python表达式编译为RediSearch的查询字符串,再发给Redis执行。例如User.find(User.age > 20)会转换为数值范围查询。这种编译是静态分析表达式树完成的,因此不能直接传变量函数,而要写在表达式内部。
对比原生redis-py,开发者需要自己拼接FT.SEARCH命令的参数,并处理JSON路径。Redis OM把这一过程隐藏,同时提供链式调用如.sort_by("age")和.page(1, 10)。但要注意,复杂逻辑如跨模型关联目前不支持,需业务层自行处理。另外,若索引未建立或字段未标index=True,查询会退化为全量扫描,性能急剧下降。
以下代码演示了组合条件查询与分页,并说明如何获取结果对象列表。可以看出,返回的是模型实例,而非原始字典,方便后续操作。
from redis_om import get_redis_connection
from redis_om import Model, Field, PrimaryKey
redis = get_redis_connection()
class User(Model):
model_config = {"storage_config": "json"}
uid: str = PrimaryKey()
name: str = Field(index=True)
age: int = Field(index=True, sortable=True)
# 查询年龄大于25且姓名包含李的用户,按年龄降序取前两条
users = User.find((User.age > 25) & User.name % "李*").sort_by("-age").page(1, 2).all()
for u in users:
print(u.uid, u.name, u.age)
生产环境避坑与性能优化
第一个常见误区是认为模型字段可以随时增减而不影响线上。实际上RediSearch索引 schema 在创建后不能自动感知模型类变化,新增索引字段需调用User.redisearch().create_index()并可能重建索引。直接改类而不重建,新字段查询永远无结果。建议在CI中加入索引迁移脚本,类比数据库迁移管理。
第二个问题是内存占用。Redis OM默认用JSON存储,每个文档有元信息开销;若数据量过亿,应考虑哈希存储或拆分大对象。同时,RediSearch索引本身消耗内存,全文索引字段越多占用越大。我们通过压测发现,在单节点16G内存下,千万级简单模型加三个索引字段尚可,但全文索引扩展到十个字段后写入延迟翻倍。
最后是连接与超时配置。库底层用redis-py连接池,但默认无重连策略。生产环境应显式设置retry_on_timeout与health_check_interval,并在Kubernetes中配置就绪探针避免雪崩。以下片段展示带参数的连接配置,可显著降低抖动期间的失败率。
from redis_om import get_redis_connection
redis = get_redis_connection(
host="127.0.0.1",
port=6379,
decode_responses=True,
retry_on_timeout=True,
socket_timeout=2,
health_check_interval=30
)