Redis OM Python
Redis OM Python is an object-mapping library that provides high-level abstractions to easily model, validate, and query data in Redis with modern Python applications. It leverages Pydantic for robust data validation and supports both Redis Hashes (`HashModel`) and JSON documents (`JsonModel`) for data storage, including automatic index generation and a fluent query API. Currently at version 1.1.0, the library maintains an active development pace with frequent updates and major version releases every few months.
Common errors
-
redis.exceptions.ConnectionError: Error 111 connecting to redis:6379. Connection refused.
cause The Python application cannot establish a connection with the Redis server. This is commonly due to Redis not running, a firewall blocking the connection, incorrect host/port configuration, or Redis binding to the wrong network interface.fixEnsure Redis is running (e.g., `docker run -d -p 6379:6379 redis/redis-stack`). Verify no firewall is blocking port 6379. Confirm the `REDIS_OM_URL` environment variable (or connection string) is correctly set to your Redis instance's address and port. -
Could not resolve field type.
cause Redis OM could not determine the type of a field in your query, often because the field annotation is missing or invalid in your model definition.fixEnsure all model fields have explicit and correct Python type annotations (e.g., `name: str`, `age: int`). If using custom types, ensure they are properly recognized by Pydantic. -
You tried to do a full-text search on the field '{field.name}', but the field is not indexed for full-text search.cause The field you are attempting to query with full-text search was not configured with `full_text_search=True` during model definition, even if `index=True` was set.fixModify your model definition to explicitly mark the field for full-text search: `field_name: str = Field(index=True, full_text_search=True)`. After updating the model, run `Migrator().run()` to update the RediSearch index. -
Customer class is NOT a subclass of BaseModel
cause This error typically occurs in a mixed Pydantic v1/v2 environment or when an external library (like `redis-om` prior to 1.0.0) was built against Pydantic v1's `BaseModel`, and the consuming application is trying to treat it as Pydantic v2's `BaseModel` directly. Redis OM 1.0+ fully supports Pydantic v2.fixEnsure you are using `redis-om` version 1.0.0 or newer. If you are, and still encountering issues, check that all other dependencies requiring Pydantic are compatible with v2. If you absolutely must use a Pydantic v1-based library alongside v2, refer to Pydantic's v1 compatibility layer (`pydantic.v1.BaseModel`). However, the recommended fix for `redis-om` is to ensure it's updated to a Pydantic v2 compatible version.
Warnings
- breaking Redis OM Python 1.0 dropped support for Python 3.8 and 3.9, requiring Python 3.10 or higher. It also requires Pydantic v2, dropping support for Pydantic v1. Existing code using older Python or Pydantic versions will break. Datetime fields are now indexed as NUMERIC (Unix timestamps) instead of TAG (ISO strings) in 1.0, impacting previous queries.
- breaking As of version 1.1.0, Redis OM Python returns UTC-aware datetimes from unmarshalling operations. This change ensures consistency and correctly handles timezones, but it might break existing applications that expected naive datetime objects or implicitly handled local timezones previously.
- gotcha Version 1.0.5 of `redis-om` was yanked from PyPI because it failed to include generated synchronous code in the wheel package, making async-only usage possible but synchronous usage broken.
- gotcha The `HashModel` in Redis OM stores data in flat Redis Hashes and therefore does not natively support nested Python container types like `list`, `set`, `dict`, or embedded other Redis OM models directly within its fields. Attempting to use these will lead to unexpected behavior or errors.
Install
-
pip install redis-om
Imports
- HashModel
from redis_om import HashModel
- JsonModel
from redis_om import JsonModel
- Field
from redis_om import Field
- Migrator
from redis_om import Migrator
Quickstart
import os
from datetime import date
from redis_om import HashModel, Migrator
# Ensure Redis Stack is running, e.g., with Docker:
# docker run -d -p 6379:6379 -p 8001:8001 redis/redis-stack
# Set the Redis connection URL (or it defaults to redis://localhost:6379)
os.environ['REDIS_OM_URL'] = os.environ.get('REDIS_OM_URL', 'redis://localhost:6379')
class Customer(HashModel):
first_name: str
last_name: str
email: str
join_date: date
age: int
class Meta:
global_key_prefix = "my_app"
model_key_prefix = "customers"
# By default, all fields are indexed in 1.0+, but can be specified individually
# for more granular control if not using a model-level index.
# Run index migrations at application startup
# For models defined as `HashModel` or `JsonModel`
Migrator().run()
# Create a customer
new_customer = Customer(
first_name="John",
last_name="Doe",
email="john.doe@example.com",
join_date=date(2023, 1, 15),
age=30
)
# Save the customer to Redis
new_customer.save()
print(f"Saved customer with PK: {new_customer.pk}")
# Retrieve the customer by its primary key (pk)
found_customer = Customer.get(new_customer.pk)
print(f"Retrieved customer: {found_customer.first_name} {found_customer.last_name}")
# Find customers by query
old_customers = Customer.find(Customer.age > 25).all()
for c in old_customers:
print(f"Old customer: {c.first_name} (Age: {c.age})")