导入redis_om的HashModel后all_pks()返回空问题排查
直接运行product.py时,Product.all_pks()能正常返回2个产品主键;但在other.py中导入product模块的Product类后,调用all_pks()返回空列表,Product.get()会抛出数据不存在异常。即便验证两个场景下Product._meta.database是同一个Redis连接,问题依然存在。
代码示例product.py:
from redis_om import get_redis_connection, HashModel redis = get_redis_connection( host="-", port=12262, password="-", decode_responses=True ) class Product(HashModel): class Meta: database = redis print(list(Product.all_pks())) # 单独运行时输出2个产品主键
other.py:
from redis_om import get_redis_connection, HashModel import product print(list(product.Product.all_pks())) # 输出空列表[]
额外测试:在other.py中重新定义与product.py完全一致的Product类后,调用all_pks()能正常获取到2个产品主键。
Redis OM的HashModel默认会根据类的完全限定名(包含模块路径的类名)生成Redis存储的key前缀。直接运行product.py时,该模块名称为__main__,对应类是__main__.Product,数据会以这个类的前缀存储;而在other.py中导入时,类的完全限定名是product.Product,Redis OM会用这个前缀查找数据,自然找不到之前用__main__.Product存储的数据。
即便两个类代码完全一致,只要类的完全限定名不同,Redis OM就会认定为不同模型,对应不同的Redis key空间。
有两种可行的解决方式:
方式一:统一数据写入的类路径
不要直接在product.py中运行数据写入逻辑,单独编写脚本通过导入product.Product类来创建数据。比如创建seed_data.py:
from product import Product # 示例:创建产品数据(按需调整字段) if not list(Product.all_pks()): Product(name="产品1", price=10).save() Product(name="产品2", price=20).save()
运行seed_data.py后,数据会以product.Product的前缀存储,此时在other.py中导入product.Product就能正常读取数据。
方式二:显式指定模型的key前缀
在product.py的Product类Meta中添加key_prefix参数,强制指定固定的key前缀,这样不管类的完全限定名是什么,都会使用这个前缀存储和查找数据:
from redis_om import get_redis_connection, HashModel redis = get_redis_connection( host="-", port=12262, password="-", decode_responses=True ) class Product(HashModel): class Meta: database = redis key_prefix = "product" # 显式指定固定前缀 print(list(Product.all_pks()))
修改后,无论直接运行product.py还是在other.py中导入,都会使用product作为key前缀,就能正常读取到数据。
内容的提问来源于stack exchange,提问作者holdmybeer1min

