Skip to content

Latest commit

 

History

History
112 lines (83 loc) · 3.4 KB

README_EN.md

File metadata and controls

112 lines (83 loc) · 3.4 KB

Cherry ORM

Python Asynchronous ORM

license pypi python

简体中文 · English

Overview

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.

Install

  • use pip: pip install cherry-orm
  • use Poetry: poetry add cherry-orm
  • use PDM: pdm add cherry-orm

Document

-> Document

Example

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()