与 FastAPI 集成

PonyORM 可以与 FastAPI 一起使用,它与 Pydantic 集成,并且可以在异步环境中使用,只要您遵循一些规则。

设置

对于您的第一步,只需按照 Pony 入门 创建数据库对象并定义您的模型。您可能希望使用 Pydantic 的内置 BaseSettings 模型 来管理您的连接密钥。具体参数可以在 连接到数据库 中找到。

import fastapi
from src.config import Settings
from src.models import db

settings = Settings()
api = fastapi.FastAPI()
db.bind(**settings.get_connection)
db.generate_mapping(create_tables=True)

模型和模式

为了充分利用 FastAPI,Pony 的模型必须与 Pydantic 的模式一起工作。不幸的是,这需要重复的模型定义。我们在这里遵循 FastAPI 的示例

以下是来自 Pony 入门 的 Pony 模型

class Person(db.Entity):
    name = Required(str)
    age = Required(int)
    cars = Set('Car')

class Car(db.Entity):
    make = Required(str)
    model = Required(str)
    owner = Required(Person)

我们希望在 FastAPI 中像这样公开 Person

@api.get('/persons')
async def read_all_persons():
    with db_session:
       persons = Person.select()
       result = [PersonInDB.from_orm(p) for p in persons]
    return result

@api.get('/person/{pid}')
async def read_single_person(pid: int):
    with db_session:
        person = Person[pid]
        result = PersonInDB.from_orm(person)
    return result

为此,我们可以编写以下 Pydantic 模式

class CarOut(BaseModel):
    make: str
    model: str

class PersonInDB(BaseModel):
    name: str
    age: int
    cars: List[CarOut]

    @validator('cars', pre=True, allow_reuse=True)
    def pony_set_to_list(cls, values):
        return [v.to_dict() for v in values]

    class Config:
        orm_mode = True

如果没有准备,Pony 的相关对象不会被正确解释。使用验证器使它们可供 Pydantic 访问。

异步和 db_session

Pony 不是为异步使用而开发的,在异步环境中正确使用它可能很棘手。但是,如果您的应用程序只有一部分是异步的,只要您坚持以下两条规则,您就可以正常使用。

您不能在异步函数上使用 @db_session 装饰器,请使用上下文管理器来包装真正与数据库交互的代码行。其次,不要在 db_session 中调用异步函数,只有普通函数调用是可能的。使用短暂的会话,不要用异步中断它们。

async def func():
    with db_session:
        thing = database.MyEntity()
    await async_func(ABC, thing)