Convert Figma logo to code with AI

redis logoredis-om-python

Object mapping, and more, for Redis and Python

1,099
108
1,099
120

Top Related Projects

12,531

Redis Python client

Object mapping, and more, for Redis and Node.js. Written in TypeScript.

1,148

Lightweight Python utilities for working with Redis

Redis management tool written in node.js

Quick Overview

Redis OM for Python is an object mapping library designed to work with Redis. It provides a high-level abstraction layer for interacting with Redis data structures, allowing developers to work with Python objects that are automatically synchronized with Redis.

Pros

  • Simplifies Redis interactions by providing an intuitive object-oriented interface
  • Supports various Redis data structures and features, including JSON, hashes, and full-text search
  • Offers automatic data validation and type checking
  • Integrates well with FastAPI for building Redis-backed APIs

Cons

  • May introduce a performance overhead compared to direct Redis operations
  • Limited to Redis-specific use cases and may not be suitable for all types of applications
  • Requires learning a new abstraction layer on top of Redis
  • Documentation could be more comprehensive for advanced use cases

Code Examples

  1. Defining a model:
from redis_om import HashModel

class Customer(HashModel):
    first_name: str
    last_name: str
    email: str
    age: int
  1. Creating and saving an instance:
customer = Customer(
    first_name="John",
    last_name="Doe",
    email="john@example.com",
    age=30
)
customer.save()
  1. Querying data:
# Find all customers named John
johns = Customer.find(Customer.first_name == "John").all()

# Find customers older than 25
adults = Customer.find(Customer.age > 25).all()
  1. Using full-text search:
from redis_om import Field, JsonModel

class Product(JsonModel):
    name: str = Field(index=True, full_text_search=True)
    description: str = Field(index=True, full_text_search=True)

# Search for products
results = Product.find("comfortable chair").all()

Getting Started

  1. Install Redis OM for Python:

    pip install redis-om
    
  2. Set up a Redis connection:

    from redis_om import get_redis_connection
    
    redis = get_redis_connection(
        host="localhost",
        port=6379,
        decode_responses=True
    )
    
  3. Define your models and start using Redis OM in your application as shown in the code examples above.

Competitor Comparisons

12,531

Redis Python client

Pros of redis-py

  • More mature and widely adopted library with extensive documentation
  • Provides low-level access to Redis commands, offering greater flexibility
  • Supports a broader range of Redis features and data structures

Cons of redis-py

  • Requires more boilerplate code for complex operations
  • Lacks built-in object mapping and schema validation

Code Comparison

redis-py:

import redis

r = redis.Redis(host='localhost', port=6379, db=0)
r.set('foo', 'bar')
value = r.get('foo')

redis-om-python:

from redis_om import HashModel

class User(HashModel):
    name: str
    age: int

user = User(name="John", age=30)
user.save()

redis-om-python is an Object Mapper for Redis, built on top of redis-py. It provides a higher-level abstraction for working with Redis data, including features like:

  • Object mapping with Pydantic models
  • Automatic schema creation and validation
  • Simplified querying and indexing

While redis-py offers more direct control over Redis operations, redis-om-python aims to simplify Redis interactions in Python applications by providing an ORM-like interface. The choice between the two depends on the specific requirements of your project and your preferred level of abstraction when working with Redis.

Object mapping, and more, for Redis and Node.js. Written in TypeScript.

Pros of redis-om-node

  • More active development with frequent updates and releases
  • Better TypeScript support and type definitions
  • Larger community and more extensive documentation

Cons of redis-om-node

  • Less mature compared to the Python version
  • May have more breaking changes due to rapid development
  • Slightly steeper learning curve for developers new to Node.js ORMs

Code Comparison

redis-om-python:

class Person(Model):
    name = TextField()
    age = IntegerField()

person = Person(name="John Doe", age=30)
person.save()

redis-om-node:

const schema = new Schema(Person, {
  name: { type: 'string' },
  age: { type: 'number' }
});

const person = await repository.createAndSave({
  name: "John Doe",
  age: 30
});

Both libraries provide similar functionality for defining models and interacting with Redis, but redis-om-node offers a more JavaScript-friendly syntax and better integration with async/await patterns. The Python version has a more straightforward and Pythonic approach to model definition and instantiation.

While both libraries aim to provide an Object-Mapping layer for Redis, they cater to different ecosystems and programming paradigms. Developers should choose based on their preferred language and specific project requirements.

1,148

Lightweight Python utilities for working with Redis

Pros of Walrus

  • More mature and established project with a longer history
  • Broader feature set, including support for more Redis data structures
  • Lightweight and flexible, allowing for lower-level Redis operations

Cons of Walrus

  • Less focus on object-relational mapping (ORM) functionality
  • May require more manual configuration and setup for complex use cases
  • Documentation could be more comprehensive and up-to-date

Code Comparison

Walrus example:

from walrus import Database
db = Database()
hash = db.Hash('my-hash')
hash.update(name='Charlie', age=30)
print(hash['name'])  # Output: Charlie

Redis OM for Python example:

from redis_om import HashModel
class Person(HashModel):
    name: str
    age: int
person = Person(name="Charlie", age=30)
person.save()
print(person.name)  # Output: Charlie

Both libraries provide ways to interact with Redis, but Redis OM for Python offers a more structured, ORM-like approach with model definitions. Walrus provides a more direct interface to Redis data structures, giving developers more flexibility but requiring more manual setup for complex scenarios.

Redis management tool written in node.js

Pros of Redis Commander

  • Provides a user-friendly web-based GUI for Redis management
  • Supports multiple Redis connections and databases
  • Offers features like data viewing, editing, and command execution

Cons of Redis Commander

  • Primarily focused on Redis administration, not application development
  • Lacks advanced ORM features and data modeling capabilities
  • May require additional setup for integration with application code

Code Comparison

Redis Commander (JavaScript):

const express = require('express');
const redisCommander = require('redis-commander');
const app = express();
redisCommander(app);
app.listen(8081);

Redis OM Python:

from redis_om import HashModel, Field

class Product(HashModel):
    name: str = Field(index=True)
    price: float = Field(index=True)
    quantity: int = Field(index=True)

Redis Commander is a web-based Redis management tool, while Redis OM Python is an Object-Relational Mapping (ORM) library for Redis. Redis Commander excels in providing a visual interface for Redis administration, making it easier to manage and inspect Redis data. On the other hand, Redis OM Python focuses on simplifying Redis interactions within Python applications, offering features like data modeling and advanced querying capabilities.

Redis Commander is more suitable for developers and administrators who need a graphical tool for Redis management, while Redis OM Python is better suited for Python developers building applications with Redis as the backend, providing a more integrated and Pythonic approach to working with Redis data.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README



Redis OM

Object mapping, and more, for Redis and Python


Version License Build Status

Redis OM Python makes it easy to model Redis data in your Python applications.

Redis OM .NET | Redis OM Node.js | Redis OM Spring | Redis OM Python

Table of contents

span

💡 Why Redis OM?

Redis OM provides high-level abstractions that make it easy to model and query data in Redis with modern Python applications.

This preview release contains the following features:

  • Declarative object mapping for Redis objects
  • Declarative secondary-index generation
  • Fluent APIs for querying Redis

💻 Installation

Installation is simple with pip, Poetry, or Pipenv.

# With pip
$ pip install redis-om

# Or, using Poetry
$ poetry add redis-om

🏁 Getting started

Starting Redis

Before writing any code you'll need a Redis instance with the appropriate Redis modules! The quickest way to get this is with Docker:

docker run -p 6379:6379 -p 8001:8001 redis/redis-stack

This launches the redis-stack an extension of Redis that adds all manner of modern data structures to Redis. You'll also notice that if you open up http://localhost:8001 you'll have access to the redis-insight GUI, a GUI you can use to visualize and work with your data in Redis.

📇 Modeling Your Data

Redis OM contains powerful declarative models that give you data validation, serialization, and persistence to Redis.

Check out this example of modeling customer data with Redis OM. First, we create a Customer model:

import datetime
from typing import Optional

from pydantic import EmailStr

from redis_om import HashModel


class Customer(HashModel):
    first_name: str
    last_name: str
    email: EmailStr
    join_date: datetime.date
    age: int
    bio: Optional[str] = None

Now that we have a Customer model, let's use it to save customer data to Redis.

import datetime
from typing import Optional

from pydantic import EmailStr

from redis_om import HashModel


class Customer(HashModel):
    first_name: str
    last_name: str
    email: EmailStr
    join_date: datetime.date
    age: int
    bio: Optional[str] = None


# First, we create a new `Customer` object:
andrew = Customer(
    first_name="Andrew",
    last_name="Brookins",
    email="andrew.brookins@example.com",
    join_date=datetime.date.today(),
    age=38,
    bio="Python developer, works at Redis, Inc."
)

# The model generates a globally unique primary key automatically
# without needing to talk to Redis.
print(andrew.pk)
# > "01FJM6PH661HCNNRC884H6K30C"

# We can save the model to Redis by calling `save()`:
andrew.save()

# Expire the model after 2 mins (120 seconds)
andrew.expire(120)

# To retrieve this customer with its primary key, we use `Customer.get()`:
assert Customer.get(andrew.pk) == andrew

Ready to learn more? Check out the getting started guide.

Or, continue reading to see how Redis OM makes data validation a snap.

✓ Validating Data With Your Model

Redis OM uses Pydantic to validate data based on the type annotations you assign to fields in a model class.

This validation ensures that fields like first_name, which the Customer model marked as a str, are always strings. But every Redis OM model is also a Pydantic model, so you can use Pydantic validators like EmailStr, Pattern, and many more for complex validations!

For example, because we used the EmailStr type for the email field, we'll get a validation error if we try to create a Customer with an invalid email address:

import datetime
from typing import Optional

from pydantic import EmailStr, ValidationError

from redis_om import HashModel


class Customer(HashModel):
    first_name: str
    last_name: str
    email: EmailStr
    join_date: datetime.date
    age: int
    bio: Optional[str] = None


try:
    Customer(
        first_name="Andrew",
        last_name="Brookins",
        email="Not an email address!",
        join_date=datetime.date.today(),
        age=38,
        bio="Python developer, works at Redis, Inc."
    )
except ValidationError as e:
    print(e)
    """
    pydantic.error_wrappers.ValidationError: 1 validation error for Customer
     email
       value is not a valid email address (type=value_error.email)
    """

Any existing Pydantic validator should work as a drop-in type annotation with a Redis OM model. You can also write arbitrarily complex custom validations!

To learn more, see the documentation on data validation.

🔎 Rich Queries and Embedded Models

Data modeling, validation, and saving models to Redis all work regardless of how you run Redis.

Next, we'll show you the rich query expressions and embedded models Redis OM provides when the RediSearch and RedisJSON modules are installed in your Redis deployment, or you're using Redis Enterprise.

TIP: Wait, what's a Redis module? If you aren't familiar with Redis modules, review the So, How Do You Get RediSearch and RedisJSON? section of this README.

Querying

Redis OM comes with a rich query language that allows you to query Redis with Python expressions.

To show how this works, we'll make a small change to the Customer model we defined earlier. We'll add Field(index=True) to tell Redis OM that we want to index the last_name and age fields:

import datetime
from typing import Optional

from pydantic import EmailStr

from redis_om import (
    Field,
    HashModel,
    Migrator
)


class Customer(HashModel):
    first_name: str
    last_name: str = Field(index=True)
    email: EmailStr
    join_date: datetime.date
    age: int = Field(index=True)
    bio: Optional[str] = None


# Now, if we use this model with a Redis deployment that has the
# RediSearch module installed, we can run queries like the following.

# Before running queries, we need to run migrations to set up the
# indexes that Redis OM will use. You can also use the `migrate`
# CLI tool for this!
Migrator().run()

# Find all customers with the last name "Brookins"
Customer.find(Customer.last_name == "Brookins").all()

# Find all customers that do NOT have the last name "Brookins"
Customer.find(Customer.last_name != "Brookins").all()

# Find all customers whose last name is "Brookins" OR whose age is
# 100 AND whose last name is "Smith"
Customer.find((Customer.last_name == "Brookins") | (
        Customer.age == 100
) & (Customer.last_name == "Smith")).all()

These queries -- and more! -- are possible because Redis OM manages indexes for you automatically.

Querying with this index features a rich expression syntax inspired by the Django ORM, SQLAlchemy, and Peewee. We think you'll enjoy it!

Note: Indexing only works for data stored in Redis logical database 0. If you are using a different database number when connecting to Redis, you can expect the code to raise a MigrationError when you run the migrator.

Embedded Models

Redis OM can store and query nested models like any document database, with the speed and power you get from Redis. Let's see how this works.

In the next example, we'll define a new Address model and embed it within the Customer model.

import datetime
from typing import Optional

from redis_om import (
    EmbeddedJsonModel,
    JsonModel,
    Field,
    Migrator,
)


class Address(EmbeddedJsonModel):
    address_line_1: str
    address_line_2: Optional[str] = None
    city: str = Field(index=True)
    state: str = Field(index=True)
    country: str
    postal_code: str = Field(index=True)


class Customer(JsonModel):
    first_name: str = Field(index=True)
    last_name: str = Field(index=True)
    email: str = Field(index=True)
    join_date: datetime.date
    age: int = Field(index=True)
    bio: Optional[str] = Field(index=True, full_text_search=True,
                               default="")

    # Creates an embedded model.
    address: Address


# With these two models and a Redis deployment with the RedisJSON
# module installed, we can run queries like the following.

# Before running queries, we need to run migrations to set up the
# indexes that Redis OM will use. You can also use the `migrate`
# CLI tool for this!
Migrator().run()

# Find all customers who live in San Antonio, TX
Customer.find(Customer.address.city == "San Antonio",
              Customer.address.state == "TX")

Calling Other Redis Commands

Sometimes you'll need to run a Redis command directly. Redis OM supports this through the db method on your model's class. This returns a connected Redis client instance which exposes a function named for each Redis command. For example, let's perform some basic set operations:

from redis_om import HashModel

class Demo(HashModel):
    some_field: str

redis_conn = Demo.db()

redis_conn.sadd("myset", "a", "b", "c", "d")

# Prints False
print(redis_conn.sismember("myset", "e"))

# Prints True
print(redis_conn.sismember("myset", "b"))

The parameters expected by each command function are those documented on the command's page on redis.io.

If you don't want to get a Redis connection from a model class, you can also use get_redis_connection:

from redis_om import get_redis_connection

redis_conn = get_redis_connection()
redis_conn.set("hello", "world")

📚 Documentation

The Redis OM documentation is available here.

⛏️ Troubleshooting

If you run into trouble or have any questions, we're here to help!

Hit us up on the Redis Discord Server or open an issue on GitHub.

✨ So How Do You Get RediSearch and RedisJSON?

Some advanced features of Redis OM rely on core features from two source available Redis modules: RediSearch and RedisJSON.

You can run these modules in your self-hosted Redis deployment, or you can use Redis Enterprise, which includes both modules.

To learn more, read our documentation.

❤️ Contributing

We'd love your contributions!

Bug reports are especially helpful at this stage of the project. You can open a bug report on GitHub.

You can also contribute documentation -- or just let us know if something needs more detail. Open an issue on GitHub to get started.

📝 License

Redis OM uses the MIT license.