No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Modificación y eliminación de datos

6/17
Recursos

Aportes 11

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

Una recomendación, antes de introducir terminología nueva(la palabra ‘commit’ luego de cada operación como update, delete, etc), explciar e lsentido de usarla-es un requerimiento de SQLAlchemy, es como darle aceptar al cambio, si fuera por método gráfico y se tuviese un botón de aceptar/rechazar los cambios

Estaba teniendo problemas al actualizar el registro, ya que la instrucción se ejecutaba correctamente, pero no le veian reflejados los cambios en la BD, lo solucioné poniendo esto, espero a alguien le sirva

db.add(result)
db.commit()
db.refresh(result)

Resumen

Modificacar datos

  1. Iniciar una Session().
  2. Si la pelicula existe, reescribir los datos
@app.put('/movies/{id}', tags=['movies'], response_model=dict, status_code=200)
def update_movie(id: int, movie: Movie)-> dict:

    db = Session()
    result = db.query(MovieModel).where(MovieModel.id == id).first()

    if result: 
        result.title = movie.title
        result.category = movie.overview
        result.overview = movie.overview
        result.rating = movie.rating
        result.year = movie.year  
        db.commit()
        return JSONResponse(status_code=201, content={"message": "Updated done"})

    
    if not result:
        return JSONResponse(status_code=404, content={'message': 'ID No found'})

Eliminar datos

  1. Iniciar una Session().
  2. Si la pelicula existe, eliminar ese registro
@app.delete('/movies/{id}', tags=['movies'], response_model=dict, status_code=200)
def delete_movie(id: int)-> dict:

    db = Session()
    result = db.query(MovieModel).where(MovieModel.id == id).first()

    if result: 
        db.delete(result)
        db.commit()
        return JSONResponse(status_code=200, content={"message": "Record deleted"})

    if not result:
        return JSONResponse(status_code=404, content={'message': 'ID No found'})

Mi aporte:

movie_update = db.query(MovieModel).filter(MovieModel.id == id).one_or_none()

Cuando solicitamos por id deberiamos usar .one_or_none(), ya que requerimos un solo objeto o en su defecto que nos devuelva None, en teoria nuestra base de datos no deberia devolver mas de un id, ya que el id es la llave primaria y se coloca en automatico. Pero en caso de que devuelva mas de un id, que es algo que no deberia hacer, va a devolver una excepción “MultipleResultsFound”

Les comparto mi put

@app.put('/movies/{id}', tags=['movies'], response_model=dict, status_code=status.HTTP_200_OK)
def update_movie(
    id: int,
    movie: Movie
) -> dict:
    db = Session()
    the_movie = db.query(MovieModel).filter(MovieModel.id == id)
    if the_movie.scalar():
        data = movie.dict()
        data['id'] = id
        the_movie.update(data, synchronize_session=False)
        db.commit()
        return JSONResponse(content={"message":"The movie was updated successfully"}, status_code=status.HTTP_200_OK)
    return JSONResponse(content={'message': "Movie no found"}, status_code=status.HTTP_404_NOT_FOUND)

Comparto mi solución al PUT

/model/movie.py

class Movie( Base ):
    __tablename__ = 'movies'

    id = Column( Integer, primary_key = True )
    title = Column( String )
    overview = Column( String )
    year = Column( Integer )
    rating = Column( Float )
    category = Column( String )


    def update( self, **kwargs ):
        for key, value in kwargs.items():
            if hasattr(self, key):
                setattr(self, key, value)

/main.py

def update_movie(id: int, movie: MovieSchema ) -> dict:
    db = Session()
    result = db.query( MovieModel ).filter( MovieModel.id == id ).first()
    if not result:
        return JSONResponse( status_code= 404, content={ 'message' : 'No encontrado' })
    update_movie = movie.dict()
    update_movie[ 'id' ] = id    
    result.update( **update_movie )
    db.commit()
    return JSONResponse( content={"message": "Se ha actualizado la pelicula"})

Les comparto mi solución al reto:

@app.get('/movies/',
         tags=['movies'],
         response_model=List[Movie]
         )
def get_movies_by_category(category: str = Query(min_length=5, max_length=15)) -> JSONResponse:
    db = Session()
    result = db.query(MovieModel).filter(MovieModel.category == category).first()
    if not result:
        return JSONResponse(status_code=404, content={'message': "Pelicula no encontrada"})
    return JSONResponse(status_code=200, content=jsonable_encoder(result))

Mi respuesta al reto anterior 😃

@app.get('/empleados/', tags=['Empleados'], response_model=List[Empleado], status_code=200)
def obtener_empleados_por_rol(rol: str =  Query(min_length=5, max_length=15)) -> List[Empleado]:
    db = Session()
    resultado = db.query(EmpleadoModel).filter(EmpleadoModel.rol == rol).all()
    if not resultado:
        return JSONResponse(status_code=404, content={'mensaje': 'No encontrado'})
    return JSONResponse(status_code=200, content=jsonable_encoder(resultado))

el commit es muy importante usarlo cuando se modifica o se crea algun registro en la bd, un compañero ejecutando una sentencia en ambiente QA se lo tiro por no usar el commit

Así queda mi put para no hardcodear los valores y en caso de que se agreguen más no sea necesario modificar la función.

@ app.put('/movies/{id}', tags=['movies'], response_model=dict, status_code=200)
def update_movie(id: int, movie: Movie) -> dict:
    db = Session()
    result = db.query(MovieModel).filter(MovieModel.id == id).first()
    if result:
        movie_attributes = [k for k, v in vars(movie).items(
        ) if not callable(v)]
        for attr in movie_attributes:
            if hasattr(result, attr) and hasattr(movie, attr):
                setattr(result, attr, getattr(movie, attr))
        db.commit()
        return JSONResponse(status_code=200, content={'message': 'Se ha modificado la película'})
    return JSONResponse(status_code=404, content={'message': 'No se encontró la película'})

Si se han preguntado como implementar el método patch, pueden hacerlo de esta manera, aunque generalmente no se usa, si quieren hacer una modificación parcial desde el frontend, pueden usar put

from fastapi import FastAPI, Depends

# Patch
class MovieUpdate(BaseModel):
    id: Optional[int] = None
    title: Optional[str] = Field(min_length=5, max_length=20)
    overview: Optional[str] = Field(min_length=15, max_length=50)
    year: Optional[int] = Field(le=2022)
    rating: Optional[float] = Field(ge=1.0, le=10.0)
    category: Optional[str] = Field(min_length=5, max_length=20)

    class Config:
        schema_extra = {
            "example": {
                "rating": 5.5,
                "category": "Acción",
            },
        }


def get_db():
    database = Session()
    try:
        yield database
    finally:
        database.close()


@app.patch("/movie/{movie_id}", tags=["movies"], response_model=dict, status_code=200)
def update_item_movie(
    movie_id: int,
    movie: MovieUpdate,
    database: Session = Depends(get_db),  # type: ignore
):
    # database = Session()
    result = database.query(MovieModel).filter(MovieModel.id == movie_id)

    if not result.first():
        return JSONResponse(content={"message": "Movie not found"}, status_code=404)

    result.update(movie.dict(exclude_unset=True))
    database.commit()

    return JSONResponse(content={"message": "Movie has modified"}, status_code=200)