Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Projeto] Resposta do Desafio - código completo

Código completo com todas as rotas. O enunciado poderia ser um pouco mais elaborado, principalmente em relação ao schema, já que não cobrimos isso em aula.

# main.py
import models
import schemas
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List
from 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('/students/', response_model=List[schemas.ResponseStudent])
def read_students(db: Session = Depends(get_db)):
    students = db.query(models.Student).all()
    return students

@app.get('/enrollments/', response_model=List[schemas.ResponseEnrollment])
def read_enrollment(db: Session = Depends(get_db)):
    enrollments = db.query(models.Enrollment).all()
    return enrollments

@app.get('/students/{student_id}', response_model=schemas.ResponseStudent)
def get_student(student_id: int, db: Session = Depends(get_db)):
    student = db.query(models.Student).filter(models.Student.id == student_id).first()
    
    if student is None:
        raise HTTPException(status_code=404, detail="Estudante não encontrado")

    return student

@app.post('/students/', response_model=schemas.ResponseStudent)
def create_student(
        student: schemas.CreateStudent,
        db: Session = Depends(get_db)
    ):
    student_db = models.Student(**student.model_dump())
    db.add(student_db)
    db.commit()
    db.refresh(student_db)
    return student_db

@app.post('/enrollments/', response_model=schemas.ResponseEnrollment)
def create_enrollment(
        enrollment: schemas.CreateEnrollment,
        db: Session = Depends(get_db)
    ):
    enrollment_db = models.Enrollment(**enrollment.model_dump())
    db.add(enrollment_db)
    db.commit()
    db.refresh(enrollment_db)
    return enrollment_db
# schemas.py
from pydantic import BaseModel, Field

class BaseStudent(BaseModel):
    name: str = Field(min_length=3, max_length=100)
    age: int = Field(gt=18, lt=100)

class CreateStudent(BaseStudent):
    pass

class ResponseStudent(BaseStudent):
    id: int
    class Config:
        from_attributes = True

class BaseEnrollment(BaseModel):
    student_id: int
    subject_name: str

class CreateEnrollment(BaseEnrollment):
    pass

class ResponseEnrollment(BaseEnrollment):
    id: int
    class Config:
        from_attributes = True
2 respostas
solução!

Oi, Gabriel! Como vai?

Agradeço por compartilhar.

Gostei da forma como você organizou as rotas e utilizou corretamente o response_model junto com os schemas. A separação entre CreateStudent e ResponseStudent, além do uso de from_attributes = True, mostra que você entendeu bem como integrar FastAPI com SQLAlchemy. Seu comentário sobre o schema faz sentido, porque essa parte exige uma abstração que nem sempre é detalhada no enunciado, mas você aplicou corretamente neste ponto.

No futuro, você pode utilizar validações personalizadas no Pydantic, como o método @field_validator, para reforçar regras de negocio.


from pydantic import BaseModel, field_validator

class Student(BaseModel):
    name: str

    @field_validator('name')
    def name_must_have_space(cls, value):
        if ' ' not in value:
            raise ValueError('nome precisa ter sobrenome')
        return value

Esse código cria uma validacao que garante que o nome tenha pelo menos nome e sobrenome.

Conteúdos relacionados
Alura

Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!

Olá, Lorena! Vou bem e você?

Muito legal a dica do @field_validator, realmente dá pra personalizar as regras de negócio de uma forma mais dinâmica. Muito obrigado!