{"id":9274,"library":"redis-om","title":"Redis OM Python","description":"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.","status":"active","version":"1.1.0","language":"en","source_language":"en","source_url":"https://github.com/redis/redis-om-python","tags":["redis","orm","odm","object-mapping","data-modeling","pydantic","search","json","database"],"install":[{"cmd":"pip install redis-om","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"Used for data validation, serialization, and deserialization. Version 2.0+ is required since redis-om 1.0.0.","package":"pydantic","optional":false},{"reason":"Dependency for advanced vector search integration, updated in redis-om 1.1.0.","package":"redisvl","optional":true}],"imports":[{"note":"Used for modeling data stored as Redis Hashes. Does not support nested container types like lists or dictionaries.","symbol":"HashModel","correct":"from redis_om import HashModel"},{"note":"Used for modeling data stored as Redis JSON documents. Supports nested container types and embedded models. Requires the RedisJSON module.","symbol":"JsonModel","correct":"from redis_om import JsonModel"},{"note":"Used for defining model fields and their indexing properties, similar to Pydantic's Field.","symbol":"Field","correct":"from redis_om import Field"},{"note":"Used to run schema migrations for RediSearch indexes.","symbol":"Migrator","correct":"from redis_om import Migrator"}],"quickstart":{"code":"import os\nfrom datetime import date\nfrom redis_om import HashModel, Migrator\n\n# Ensure Redis Stack is running, e.g., with Docker:\n# docker run -d -p 6379:6379 -p 8001:8001 redis/redis-stack\n\n# Set the Redis connection URL (or it defaults to redis://localhost:6379)\nos.environ['REDIS_OM_URL'] = os.environ.get('REDIS_OM_URL', 'redis://localhost:6379')\n\nclass Customer(HashModel):\n    first_name: str\n    last_name: str\n    email: str\n    join_date: date\n    age: int\n\n    class Meta:\n        global_key_prefix = \"my_app\"\n        model_key_prefix = \"customers\"\n        # By default, all fields are indexed in 1.0+, but can be specified individually\n        # for more granular control if not using a model-level index.\n\n# Run index migrations at application startup\n# For models defined as `HashModel` or `JsonModel`\nMigrator().run()\n\n# Create a customer\nnew_customer = Customer(\n    first_name=\"John\",\n    last_name=\"Doe\",\n    email=\"john.doe@example.com\",\n    join_date=date(2023, 1, 15),\n    age=30\n)\n\n# Save the customer to Redis\nnew_customer.save()\nprint(f\"Saved customer with PK: {new_customer.pk}\")\n\n# Retrieve the customer by its primary key (pk)\nfound_customer = Customer.get(new_customer.pk)\nprint(f\"Retrieved customer: {found_customer.first_name} {found_customer.last_name}\")\n\n# Find customers by query\nold_customers = Customer.find(Customer.age > 25).all()\nfor c in old_customers:\n    print(f\"Old customer: {c.first_name} (Age: {c.age})\")\n","lang":"python","description":"This quickstart demonstrates defining a `HashModel`, connecting to Redis via an environment variable, running schema migrations, creating and saving model instances, and retrieving them by primary key and through a basic query. It assumes a Redis Stack instance is running locally (e.g., via Docker)."},"warnings":[{"fix":"Upgrade Python to 3.10+ and Pydantic to v2. Migrate Pydantic v1 code to v2 syntax (e.g., `@validator` to `@field_validator`, `Config` class to `model_config = ConfigDict(...)`). If migrating from 0.x, refer to the Redis OM Python 0.x to 1.0 Migration Guide for detailed steps, including schema and data migration commands (`om migrate`, `om migrate-data run`).","message":"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.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Adjust application logic to explicitly handle UTC-aware datetimes. If naive datetimes are still desired, convert the UTC-aware datetimes back to naive local time within your application after retrieval (e.g., `dt_obj.astimezone(None)`).","message":"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.","severity":"breaking","affected_versions":">=1.1.0"},{"fix":"Avoid using version 1.0.5. If using a specific version, ensure it's 1.0.6 or newer for stable synchronous and asynchronous support. Pip will typically install 1.0.6 if 1.0.5 is yanked, but explicit pinning should be checked.","message":"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.","severity":"gotcha","affected_versions":"1.0.5"},{"fix":"For models requiring nested data structures or embedded models, use `JsonModel` instead of `HashModel`. `JsonModel` serializes the data as JSON, allowing for complex nested objects.","message":"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.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure 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.","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.","error":"redis.exceptions.ConnectionError: Error 111 connecting to redis:6379. Connection refused."},{"fix":"Ensure 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.","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.","error":"Could not resolve field type."},{"fix":"Modify 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.","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.","error":"You tried to do a full-text search on the field '{field.name}', but the field is not indexed for full-text search."},{"fix":"Ensure 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.","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.","error":"Customer class is NOT a subclass of BaseModel"}]}