Я недавно узнал о fastAPI и проработал учебник и другие документы. Хотя fastAPI довольно хорошо документирован, я не смог найти информацию о том, как обрабатывать вложенные данные при работе с базой данных.
Для тестирования я написал очень маленькое семейство API с двумя моделями:
class Member(Base):
__tablename__ = 'members'
id = Column(Integer, primary_key=True, server_default=text("nextval('members_id_seq'::regclass)"))
name = Column(String(128), nullable=False)
age = Column(Integer, nullable=True)
family_id = Column(Integer, ForeignKey('families.id', deferrable=True, initially='DEFERRED'), nullable=False, index=True)
family = relationship("Family", back_populates="members")
class Family(Base):
__tablename__ = 'families'
id = Column(Integer, primary_key=True, server_default=text("nextval('families_id_seq'::regclass)"))
family_name = Column(String(128), nullable=False)
members = relationship("Member", back_populates="family")
, и я создал Postgres базу данных с двумя таблицами и описанными отношениями Вот. С помощью определений схемы и файла crud, как в учебном пособии по fastAPI, я могу создавать отдельные семейства и члены и просматривать их во вложенном виде с помощью запроса get. Вот вложенная схема:
class Family(FamilyBase):
id: int
members: List[Member]
class Config:
orm_mode = True
Пока все хорошо. Теперь я хотел бы добавить представление поста, которое принимает вложенную структуру в качестве входных данных и соответственно заполняет базу данных. Документация в https://fastapi.tiangolo.com/tutorial/body-nested-models/ показывает, как это сделать в принципе, но она пропускает часть базы данных (то есть crud).
Поскольку входные данные не будут иметь полей id
и, очевидно, не Не нужно указывать family_id
, у меня есть схема MemberStub
и схема NestedFamilyCreate
следующим образом:
class MemberStub(BaseModel):
name: str
age: int
class NestedFamilyCreate(BaseModel):
family_name: str
members: List[MemberStub]
В моей процедуре маршрутизации families.py
У меня есть:
@app.post('/nested-families/', response_model=schemas.Family)
def create_family(family: schemas.NestedFamilyCreate, db: Session = Depends(get_db)):
# no check for previous existence as names can be duplicates
return crud.create_nested_family(db=db, family=family)
(response_model указывает на вложенное представление семьи со всеми членами, включая все идентификаторы; см. Выше).
Я не могу понять, как написать подпрограмму crud.create_nested_family
. На основе простого создания, как в учебном пособии, это выглядит следующим образом:
def create_nested_family(db: Session, family: schemas.NestedFamilyCreate):
# split information in family and members
members = family.members
core_family = None # ??? This is where I get stuck
db_family = models.Family(**family.dict()) # This fails
db.add(db_family)
db.commit()
db.refresh(db_family)
return db_family
Итак, я могу извлечь членов и могу через них l oop, но сначала мне нужно будет создать новый db_family
запись, которая не должна содержать участников. Затем, с db.refresh
, я вернул бы новый family_id, который я мог бы добавить к каждой записи members
. Но как я могу это сделать? Если я понимаю, что здесь требуется, мне нужно было бы добиться некоторого отображения моей вложенной схемы в простую схему для FamilyCreate (которая работает сама по себе) и в простую схему для MemberCreate (которая также работает сама по себе). Но как я могу это сделать?