我使用FastAPI、sqlalchemy和pydantic构建了一个API。ORM建模工作了一段时间,但我更新了代码,并以某种方式破坏了关系映射。请帮我找出我在我的ORM映射中做错了什么。
当我去http://localhost:8000/test-rel的时候,我希望看到这样的情景:
[{"name":"P One","pk_id":1,"fk_id":1, "test":{"test_id":1, "test_name":"One"}},{"name":"P Two","pk_id":2,"fk_id":2, "test":{"test_id":2, "test_name":"Two"}},{"name":"P Three","pk_id":3,"fk_id":null, "test": null}]
但我看到的却是:
[{"name":"P One","pk_id":1,"fk_id":1},{"name":"P Two","pk_id":2,"fk_id":2},{"name":"P Three","pk_id":3,"fk_id":null}]
下面是我项目中用于排除故障的测试代码部分:
schemas.py
from typing import Optional
from pydantic import BaseModel
class Test(BaseModel):
test_id: int
test_name: str
class TestP(BaseModel):
pk_id: int
fk_id: Optional[int]
name: Optional[str]
test: Test
class Config:
orm_mode = True
models.py
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, DATE, DECIMAL
from sqlalchemy.orm import relationship
from sql_app.database import Base
class Test(Base):
__tablename__ = "test"
test_id = Column(Integer, primary_key=True)
test_name = Column(String)
class TestP(Base):
__tablename__ = "test_p"
pk_id = Column(Integer, primary_key=True)
fk_id = Column(Integer, ForeignKey("test.test_id"), nullable=True)
name = Column(String, nullable=True)
test = relationship("Test")
database.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
import urllib
params = urllib.parse.quote_plus("DRIVER={SQL Server Native Client 11.0};"
"SERVER=SQLEXPRESS;"
"DATABASE=Test;"
"Trusted_Connection=yes")
engine = create_engine(
"mssql+pyodbc:///?odbc_connect={}".format(params)
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
crud.py
from sqlalchemy.orm import Session
from sqlalchemy import and_, update, delete
from fastapi.encoders import jsonable_encoder
from typing import List
from sql_app import models
from sql_app import schemas
def test_rel(db: Session) -> List[schemas.TestP]:
return db.query(models.TestP).all()
main.py
import babel.numbers as bn
from fastapi import Depends, FastAPI, HTTPException, Request
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy.orm import Session
from sql_app import crud, models, schemas
from sql_app.database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/test-rel/")
def test_rel(db: Session = Depends(get_db)):
return crud.test_rel(db=db)
发布于 2021-07-08 14:29:41
回答了CaseIIT:关于github的讨论
几件事:
def test_rel(db: Session) -> List[schemas.TestP]:
return db.query(models.TestP).all()
This returns a List[model.TestP]
此外,默认情况下,这些关系是延迟加载的。查看https://docs.sqlalchemy.org/en/14/orm/loading_relationships.html以获得急切的加载选项
我的回答是:,这正是我想要的。我没有意识到,默认情况下,关系是延迟加载的。我的代码使用pydantic来验证响应,而我的查询没有通过验证,因为pydantic验证没有看到已连接的表。我更新了我的代码,以添加急切的加载,现在它正按照我的预期工作。
test = relationship("Test", lazy='joined')
https://stackoverflow.com/questions/68292548
复制相似问题