Hello,
I'm trying to pass pydantic models to sqlalchemy models based on sql-databases doc.
It works well for single models but fails to work with relationship. I'm expecting to receive an objet nesting several other objects in my endpoint.
Is there a way to do that using the BaseModel.dict() like in the documentation or do I need to map my pydantic model to my sqlalchemy model in order to achieve this?
Example
from typing import Optional, List
from fastapi import Depends, FastAPI, HTTPException
from pydantic import BaseModel
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session, sessionmaker, relationship
from sqlalchemy import ForeignKey, Column, Integer, String
Base = declarative_base()
class Parent(Base):
__tablename__ = "parents"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(255), index=True)
children = relationship("Child", back_populates="parent")
class Child(Base):
__tablename__ = "children"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(255), index=True)
parent_id = Column('parent_id', Integer(), ForeignKey('parents.id'), nullable=False)
parent = relationship("Parent", back_populates="children")
class ChildSchema(BaseModel):
id: Optional[int]
name: str
class Config:
orm_mode = True
class ParentSchema(BaseModel):
id: Optional[int]
name: str
children: List[ChildSchema] = []
class Config:
orm_mode = True
SQLALCHEMY_DATABASE_URL = "sqlite:///./test_app.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base.metadata.create_all(bind=engine)
api = FastAPI()
def get_db():
try:
db = SessionLocal()
yield db
finally:
db.close()
@api.post("/parents/", response_model=ParentSchema)
def post_parent(parent: ParentSchema, db: Session = Depends(get_db)):
db_parent = Parent(**parent.dict())
db.add(db_parent)
db.commit()
db.refresh(db_parent)
return ParentSchema.from_orm(db_parent)
if __name__ == "__main__":
from fastapi.testclient import TestClient
client = TestClient(api)
# this works
data1 = """{"name": "string"}"""
response = client.post("/parents/", data=data1)
assert response.status_code == 200
# this does not work
data2 = """{"name": "string", "children": [{"name": "string"}]}"""
response = client.post("/parents/", data=data2)
assert response.status_code == 200
Description
data1 works well as expected.
data2 raise AttributeError: 'dict' object has no attribute '_sa_instance_state'
Environment
- FastAPI Version: 0.58.0
- Python version: Python 3.7.7
Hello,
I'm trying to pass pydantic models to sqlalchemy models based on sql-databases doc.
It works well for single models but fails to work with relationship. I'm expecting to receive an objet nesting several other objects in my endpoint.
Is there a way to do that using the
BaseModel.dict()like in the documentation or do I need to map my pydantic model to my sqlalchemy model in order to achieve this?Example
Description
data1 works well as expected.
data2 raise AttributeError: 'dict' object has no attribute '_sa_instance_state'
Environment