【发布时间】:2022-08-16 19:03:45
【问题描述】:
我无法理解如何使用 FastAPI 和 SQLModel 以一对多的关系显示子数据。我正在使用 Python 3.10.3、FastAPI 版本 0.78.0 和 SQLModel 版本 0.0.6。这是父/子数据库模型的简化版本:
from datetime import datetime
from email.policy import default
from sqlalchemy import UniqueConstraint
from sqlmodel import Field, SQLModel, Relationship
class CustomerBase(SQLModel):
__table_args__ = (UniqueConstraint(\"email\"),)
first_name: str
last_name: str
email: str
active: bool | None = True
class Customer(CustomerBase, table=True):
id: int | None =Field(primary_key=True, default=None)
class CustomerCreate(CustomerBase):
pass
class CustomerRead(CustomerBase):
id: int
class CustomerReadWithCalls(CustomerRead):
calls: list[\"CallRead\"] = []
class CallBase(SQLModel):
duration: int
cost_per_minute: int | None = None
customer_id: int | None = Field(default=None, foreign_key=\"customer.id\")
created: datetime = Field(nullable=False, default=datetime.now().date())
class Call(CallBase, table=True):
id: int | None = Field(primary_key=True)
class CallCreate(CallBase):
pass
class CallRead(CallBase):
id: int
class CallReadWithCustomer(CallRead):
customer: CustomerRead | None
这是API路线:
from fastapi import APIRouter, HTTPException, Depends, Query
from rbi_app.crud.customer import (
get_customers,
get_customer,
)
from rbi_app.models import (
CustomerRead,
CustomerReadWithCalls,
)
from rbi_app.database import Session, get_session
router = APIRouter()
@router.get(\"/customers/\", status_code=200, response_model=list[CustomerRead])
def read_customers(
email: str = \"\",
offset: int = 0,
limit: int = Query(default=100, lte=100),
db: Session = Depends(get_session)
):
return get_customers(db, email, offset=offset, limit=limit)
@router.get(\"/customers/{customer_id}\", status_code=200, response_model=CustomerReadWithCalls)
def read_customer(id: int, db: Session = Depends(get_session)):
customer = get_customer(db, id)
if customer is None:
raise HTTPException(status_code=404, detail=f\"Customer not found for {id=}\")
return customer
以下是 API Route 端点对数据库的查询:
from sqlmodel import select
from rbi_app.database import Session
from rbi_app.models import (
Customer,
CustomerCreate,
)
# from rbi_app.schemas.customer import CustomerCreate
def get_customer(db: Session, id: int):
return db.get(Customer, id)
def get_customers(db: Session, email: str = \"\", offset: int = 0, limit: int = 100):
if email:
return db.exec(select(Customer).where(Customer.email == email)).first()
return db.exec(select(Customer).offset(offset).limit(limit).order_by(Customer.id)).all()
当我导航到获取所有客户的路线时,我的查询运行并获得了客户,但客户中没有“呼叫”列表属性。 OpenAPI 显示显示“调用”属性,但它是空的。
我究竟做错了什么?任何建议或参考将不胜感激!
-
如果没有 API 路由部分,就很难说出哪里出了问题。此外,我们缺少查询,但我猜 pydantic 使用空数组初始化
calls字段,因为您没有将calls提取/添加到响应中。 -
也许是因为调用不是急切加载的。查看 SQLModel 问题中的this comment 以获取更多信息。
-
你是对的,我应该包括 API 路由和实际查询。更改了 OP 以更改此设置。
标签: python fastapi pydantic sqlmodel