Python Asynchronous ORM
简体中文 · English
Cherry ORM
is an asynchronous object relational mapping (ORM) library for Python. It is based on SQLAlchemy Core and Pydantic V2.
All of its design is designed to be simple and easy to use, greatly reducing the cost of database operation for developers, improving development efficiency, and allowing developers to focus more on the implementation of business logic.
- use pip:
pip install cherry-orm
- use Poetry:
poetry add cherry-orm
- use PDM:
pdm add cherry-orm
-> Document
from datetime import date
from typing import List, Optional
import cherry
db = cherry.Database("sqlite+aiosqlite:///:memory:")
class Student(cherry.Model):
id: int = cherry.Field(primary_key=True)
name: str = cherry.Field(unique=True, index=True)
age: int
birthday: date = cherry.Field(default_factory=date.today)
school: cherry.ForeignKey[Optional["School"]] = None
cherry_config = cherry.CherryConfig(tablename="student", database=db)
class School(cherry.Model):
id: cherry.PrimaryKey[int]
name: str = cherry.Field(unique=True, index=True)
students: cherry.ReverseRelation[List[Student]] = []
cherry_config = cherry.CherryConfig(tablename="school", database=db)
async def main():
await db.init()
# insert
school = await School(id=1, name="school 1").insert()
student1 = await Student(id=1, name="student 1", age=15, school=school).insert()
await Student(id=2, name="student 2", age=18, school=school).insert()
await Student(id=3, name="student 3", age=20, school=school).insert()
# update
student1.age += 1
await student1.save()
# or
await student1.update(age=19)
# get related model
await school.fetch_related(School.students)
assert len(school.students) == 3
# conditional query
# Pythonic style
student2: Student = await Student.filter(Student.name == "student 2").get()
# Django style
student2: Student = await Student.filter(name="student 2").get()
students: List[Student] = await Student.filter(Student.age >= 18).all()
# aggregate query
student_nums: int = await Student.filter(Student.age >= 18).count()
assert len(students) == student_nums
student_age_avg: Optional[int] = await Student.select().avg(Student.age)
# prefetch related model in query
student_with_school: Student = (
await Student.filter(Student.name == "student 3")
.prefetch_related(Student.school)
.get()
)
# select for update
await Student.select().update(birthday=date(2023, 10, 1))
# select for delete
await Student.filter(Student.age >= 20).delete()