Description
HashModel.save() raises ResponseError: unknown command 'HTTL' on any Redis server older than 7.4.
The root cause is supports_hash_field_expiration() checking only the redis-py client version, not the Redis server version:
# redis_om/model/model.py
def supports_hash_field_expiration():
try:
import redis as redis_lib
version_str = getattr(redis_lib, "__version__", "0.0.0")
version_parts = tuple(int(x) for x in version_str.split(".")[:3])
if version_parts >= (5, 1, 0):
return hasattr(redis_lib.asyncio.Redis, "hexpire") # always True with redis-py 5.x
return False
except (ValueError, AttributeError):
return False
With redis-py >= 5.1.0 installed, this always returns True, so save() unconditionally calls HTTL — a command only available since Redis 7.4.
Reproduction
from redis_om.model.model import supports_hash_field_expiration
import redis as redis_lib
print("redis-py version:", redis_lib.__version__)
# redis-py version: 5.3.1
print("supports_hash_field_expiration():", supports_hash_field_expiration())
# supports_hash_field_expiration(): True ← wrong: only checks client
conn = redis_lib.Redis.from_url("redis://localhost:6379/0")
print("Redis server version:", conn.info("server").get("redis_version"))
# Redis server version: 6.2.18 ← server doesn't support HTTL
Then calling .save() on any HashModel:
redis.exceptions.ResponseError: unknown command `HTTL`, with args beginning with:
`myapp:mymodel:some-key`, `FIELDS`, `2`, `field1`, `field2`
Expected behaviour
supports_hash_field_expiration() should verify the connected Redis server is ≥ 7.4 before returning True. Checking only the client library version is insufficient.
Environment
redis-om: 1.1.0
redis-py: 5.3.1
- Redis server: 6.2.18 (also reproducible on any Redis < 7.4, including Azure Cache for Redis)
- Python: 3.13
Description
HashModel.save()raisesResponseError: unknown command 'HTTL'on any Redis server older than 7.4.The root cause is
supports_hash_field_expiration()checking only the redis-py client version, not the Redis server version:With
redis-py >= 5.1.0installed, this always returnsTrue, sosave()unconditionally callsHTTL— a command only available since Redis 7.4.Reproduction
Then calling
.save()on anyHashModel:Expected behaviour
supports_hash_field_expiration()should verify the connected Redis server is ≥ 7.4 before returningTrue. Checking only the client library version is insufficient.Environment
redis-om: 1.1.0redis-py: 5.3.1