Remove stub documentation in favor of GH Issues
This commit is contained in:
parent
cab1fc308a
commit
4a4d0b432d
9 changed files with 95 additions and 179 deletions
17
README.md
17
README.md
|
@ -33,11 +33,13 @@ span
|
||||||
- [📇 Modeling Your Data](#-modeling-your-data)
|
- [📇 Modeling Your Data](#-modeling-your-data)
|
||||||
- [✓ Validating Data With Your Model](#-validating-data-with-your-model)
|
- [✓ Validating Data With Your Model](#-validating-data-with-your-model)
|
||||||
- [🔎 Rich Queries and Embedded Models](#-rich-queries-and-embedded-models)
|
- [🔎 Rich Queries and Embedded Models](#-rich-queries-and-embedded-models)
|
||||||
|
- [Querying](#querying)
|
||||||
|
- [Embedded Models](#embedded-models)
|
||||||
- [💻 Installation](#-installation)
|
- [💻 Installation](#-installation)
|
||||||
- [📚 Documentation](#-documentation)
|
- [📚 Documentation](#-documentation)
|
||||||
- [⛏️ Troubleshooting](#-troubleshooting)
|
- [⛏️ Troubleshooting](#️-troubleshooting)
|
||||||
- [✨ So, How Do You Get RediSearch and RedisJSON?](#-so-how-do-you-get-redisearch-and-redisjson)
|
- [✨ So How Do You Get RediSearch and RedisJSON?](#-so-how-do-you-get-redisearch-and-redisjson)
|
||||||
- [❤️ Contributing](#-contributing)
|
- [❤️ Contributing](#️-contributing)
|
||||||
- [📝 License](#-license)
|
- [📝 License](#-license)
|
||||||
|
|
||||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
|
@ -199,7 +201,7 @@ from redis_om import (
|
||||||
)
|
)
|
||||||
from redis_om import get_redis_connection
|
from redis_om import get_redis_connection
|
||||||
|
|
||||||
|
|
||||||
class Customer(HashModel):
|
class Customer(HashModel):
|
||||||
first_name: str
|
first_name: str
|
||||||
last_name: str = Field(index=True)
|
last_name: str = Field(index=True)
|
||||||
|
@ -235,8 +237,6 @@ These queries -- and more! -- are possible because **Redis OM manages indexes fo
|
||||||
|
|
||||||
Querying with this index features a rich expression syntax inspired by the Django ORM, SQLAlchemy, and Peewee. We think you'll enjoy it!
|
Querying with this index features a rich expression syntax inspired by the Django ORM, SQLAlchemy, and Peewee. We think you'll enjoy it!
|
||||||
|
|
||||||
To learn more about how to query with Redis OM, see the [documentation on querying](docs/querying.md).
|
|
||||||
****
|
|
||||||
### Embedded Models
|
### 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.
|
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.
|
||||||
|
@ -292,8 +292,6 @@ Customer.find(Customer.address.city == "San Antonio",
|
||||||
Customer.address.state == "TX")
|
Customer.address.state == "TX")
|
||||||
```
|
```
|
||||||
|
|
||||||
To learn more, read the [documentation on embedded models](docs/embedded.md).
|
|
||||||
|
|
||||||
## 💻 Installation
|
## 💻 Installation
|
||||||
|
|
||||||
Installation is simple with `pip`, Poetry, or Pipenv.
|
Installation is simple with `pip`, Poetry, or Pipenv.
|
||||||
|
@ -314,8 +312,7 @@ The Redis OM documentation is available [here](docs/index.md).
|
||||||
|
|
||||||
If you run into trouble or have any questions, we're here to help!
|
If you run into trouble or have any questions, we're here to help!
|
||||||
|
|
||||||
First, check the [FAQ](docs/faq.md). If you don't find the answer there,
|
Hit us up on the [Redis Discord Server](http://discord.gg/redis) or [open an issue on GitHub](https://github.com/redis-developer/redis-om-python/issues/new).
|
||||||
hit us up on the [Redis Discord Server](http://discord.gg/redis).
|
|
||||||
|
|
||||||
## ✨ So How Do You Get RediSearch and RedisJSON?
|
## ✨ So How Do You Get RediSearch and RedisJSON?
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
# Managing Connections
|
|
||||||
|
|
||||||
WIP!
|
|
|
@ -1,54 +0,0 @@
|
||||||
# Embedded Models
|
|
||||||
|
|
||||||
**NOTE:** This documentation is a stub, using the same embedded JSON model example as the README.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
```python
|
|
||||||
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]
|
|
||||||
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")
|
|
||||||
```
|
|
|
@ -1,3 +0,0 @@
|
||||||
# Frequently Asked Questions (FAQ)
|
|
||||||
|
|
||||||
WIP!
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
This section includes a complete example showing how to integrate Redis OM with FastAPI.
|
Good news: Redis OM was specifically designed to integrate with FastAPI!
|
||||||
|
|
||||||
Good news: Redis OM was **specifically designed to integrate with FastAPI**!
|
This section includes a complete example showing how to integrate Redis OM with FastAPI.
|
||||||
|
|
||||||
## Concepts
|
## Concepts
|
||||||
|
|
||||||
|
@ -131,4 +131,89 @@ Get a copy of the value for "pk" and make another request to get that customer:
|
||||||
You can also get a list of all customer PKs:
|
You can also get a list of all customer PKs:
|
||||||
|
|
||||||
$ curl "http://localhost:8000/customers"
|
$ curl "http://localhost:8000/customers"
|
||||||
{"customers":["01FM2G8EP38AVMH7PMTAJ123TA"]}
|
{"customers":["01FM2G8EP38AVMH7PMTAJ123TA"]}
|
||||||
|
|
||||||
|
## Redsi OM with Asyncio
|
||||||
|
|
||||||
|
Redis OM is designed to work with asyncio, so you can use Redis OM models asynchronously within FastAPI applications.
|
||||||
|
|
||||||
|
The only difference is that you import the Redis OM models from the `aredis_om` module instead of the `redis_om` module.
|
||||||
|
|
||||||
|
Here is the previous FastAPI app, but using asyncio-compatible Redis OM code:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import datetime
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
import aioredis
|
||||||
|
|
||||||
|
from fastapi import FastAPI, HTTPException
|
||||||
|
from starlette.requests import Request
|
||||||
|
from starlette.responses import Response
|
||||||
|
|
||||||
|
from fastapi_cache import FastAPICache
|
||||||
|
from fastapi_cache.backends.redis import RedisBackend
|
||||||
|
from fastapi_cache.decorator import cache
|
||||||
|
|
||||||
|
from pydantic import EmailStr
|
||||||
|
|
||||||
|
from aredis_om import HashModel, NotFoundError # <- Notice, we import from aredis_om
|
||||||
|
from aredis_om import get_redis_connection
|
||||||
|
|
||||||
|
# This Redis instance is tuned for durability.
|
||||||
|
REDIS_DATA_URL = "redis://localhost:6380"
|
||||||
|
|
||||||
|
# This Redis instance is tuned for cache performance.
|
||||||
|
REDIS_CACHE_URL = "redis://localhost:6381"
|
||||||
|
|
||||||
|
|
||||||
|
class Customer(HashModel):
|
||||||
|
first_name: str
|
||||||
|
last_name: str
|
||||||
|
email: EmailStr
|
||||||
|
join_date: datetime.date
|
||||||
|
age: int
|
||||||
|
bio: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/customer")
|
||||||
|
async def save_customer(customer: Customer):
|
||||||
|
# We can save the model to Redis by calling `save()`:
|
||||||
|
return await customer.save() # <- We use await here
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/customers")
|
||||||
|
async def list_customers(request: Request, response: Response):
|
||||||
|
# To retrieve this customer with its primary key, we use `Customer.get()`:
|
||||||
|
return {"customers": await Customer.all_pks()} # <- We also use await here
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/customer/{pk}")
|
||||||
|
@cache(expire=10)
|
||||||
|
async def get_customer(pk: str, request: Request, response: Response):
|
||||||
|
# To retrieve this customer with its primary key, we use `Customer.get()`:
|
||||||
|
try:
|
||||||
|
return await Customer.get(pk) # <- And, finally, one more await!
|
||||||
|
except NotFoundError:
|
||||||
|
raise HTTPException(status_code=404, detail="Customer not found")
|
||||||
|
|
||||||
|
|
||||||
|
@app.on_event("startup")
|
||||||
|
async def startup():
|
||||||
|
r = aioredis.from_url(REDIS_CACHE_URL, encoding="utf8",
|
||||||
|
decode_responses=True)
|
||||||
|
FastAPICache.init(RedisBackend(r), prefix="fastapi-cache")
|
||||||
|
|
||||||
|
# You can set the Redis OM URL using the REDIS_OM_URL environment
|
||||||
|
# variable, or by manually creating the connection using your model's
|
||||||
|
# Meta object.
|
||||||
|
Customer.Meta.database = get_redis_connection(url=REDIS_DATA_URL,
|
||||||
|
decode_responses=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
**NOTE:** The modules `redis_om` and `aredis_om` are identical in almost every
|
||||||
|
way. The only difference is that the `aredis_om` returns coroutines that you must
|
||||||
|
`await`.
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
# Integration Redis OM With Popular Frameworks
|
|
||||||
|
|
||||||
WIP!
|
|
|
@ -1,31 +0,0 @@
|
||||||
# Models and Fields
|
|
||||||
|
|
||||||
**NOTE:** This documentation is a stub. Documentation for this project is a work in progress!
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
## Saving Data As Hashes With HashModel
|
|
||||||
|
|
||||||
### What Does Redis Store?
|
|
||||||
|
|
||||||
## Saving Data With JSON With JsonModel
|
|
||||||
|
|
||||||
### What Does Redis Store?
|
|
||||||
|
|
||||||
## Primary Keys
|
|
||||||
|
|
||||||
### Why Primary Keys Matter to Redis OM
|
|
||||||
|
|
||||||
### Using the Default Primary Key
|
|
||||||
|
|
||||||
### Using a Custom Primary Key
|
|
||||||
|
|
||||||
## Meta Classes
|
|
||||||
|
|
||||||
## Subclassing Models
|
|
||||||
|
|
||||||
### Subclassing and Meta Objects
|
|
||||||
|
|
||||||
## Saving Models
|
|
||||||
|
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
# Querying
|
|
||||||
|
|
||||||
**NOTE:** This documentation is a stub that uses examples from other documentation in this project (the README, the Getting Started guide, etc.). Detailed documentation on querying in a work in progress.
|
|
||||||
|
|
||||||
Querying in Redis OM uses a rich expression syntax inspired by the Django ORM, SQLAlchemy, and Peewee.
|
|
||||||
|
|
||||||
In the following example, we define `Address` and `Customer` models for use with a Redis database that has the [RedisJSON](redis-json-url) module installed.
|
|
||||||
|
|
||||||
With these two classes defined, we can query on any indexed fields in the models -- including indexed fields within embedded models.
|
|
||||||
|
|
||||||
```python
|
|
||||||
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]
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
# 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()
|
|
||||||
|
|
||||||
# Here are a few example queries that use these two models...
|
|
||||||
|
|
||||||
# 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()
|
|
||||||
|
|
||||||
# Find all customers who live in San Antonio, TX
|
|
||||||
Customer.find(Customer.address.city == "San Antonio",
|
|
||||||
Customer.address.state == "TX")
|
|
||||||
```
|
|
|
@ -1,5 +0,0 @@
|
||||||
# Testing Your Models
|
|
||||||
|
|
||||||
**NOTE:** This documentation is a Work in Progress.
|
|
||||||
|
|
||||||
Writing tests that use a Redis OM model requires some setup. For now, review the tests in the redis-om-python project for examples.
|
|
Loading…
Reference in a new issue