No tienes acceso a esta clase

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

Curso de FastAPI

Curso de FastAPI

Luis Martínez

Luis Martínez

Crear un CRUD básico en FastAPI: Eliminar

10/23
Recursos

Crear y gestionar endpoints es fundamental para un CRUD completo en FastAPI. Aquí se explora cómo implementar la funcionalidad de detalle, borrado y actualización de clientes en una API. A lo largo de este proceso, se observa cómo manejar la consulta, validación y actualización de datos en la base de datos de manera robusta.

¿Cómo obtener el detalle de un cliente?

Para obtener el detalle de un cliente, es esencial recibir el customer_id y utilizar la sesión de la base de datos. Aquí se plantea una estructura básica:

  • Declaración de Ruta: Usamos app.get("/customer/{customer_id}") para definir la URL, en la que {customer_id} permite identificar el cliente específico.
  • Consulta en la Base de Datos: La sesión de la base de datos ejecuta get con el modelo y el customer_id.
  • Manejo de Errores: Si el cliente no existe, se lanza una excepción HTTPException con un código 404 Not Found y un mensaje personalizado, como Customer does not exist, asegurando claridad en la respuesta JSON.

Esta estructura asegura que el cliente pueda consultarse de manera efectiva y que, en caso de no hallarse, el usuario reciba un mensaje adecuado.

¿Cómo borrar un cliente en FastAPI?

Para implementar el endpoint de borrado, se reutiliza en gran medida el código de consulta:

  • Ruta de Borrado: Cambiamos el método a delete para el endpoint "/customer/{customer_id}", respetando la estructura previa.
  • Eliminación de Cliente: Una vez localizado el cliente, se usa session.delete() con el objeto correspondiente.
  • Confirmación de Eliminación: Finalizamos con session.commit() para confirmar el cambio en la base de datos. La respuesta JSON debe incluir un mensaje como {"detail": "Customer deleted successfully"} para asegurar al usuario que la eliminación se realizó con éxito.

Este proceso garantiza que el cliente se elimine completamente de la base de datos solo si existe.

¿Cómo actualizar un cliente en FastAPI?

Para completar el CRUD, solo falta el endpoint de actualización. Este implica recibir un cuerpo (body) con los datos actualizados:

  • Crear la Ruta y Función: Define un nuevo endpoint put o patch para actualizar. Se recibe el customer_id y el objeto con los nuevos datos, excluyendo el ID.
  • Validación y Actualización: Como en los otros endpoints, verifica que el cliente exista. Luego, actualiza los campos necesarios en el objeto del cliente.
  • Confirmación de Actualización: Usa session.commit() para guardar los cambios.

Este endpoint permite modificar los datos del cliente según lo necesite el usuario, proporcionando flexibilidad y manteniendo la integridad de los datos en la base de datos.

Aportes 13

Preguntas 0

Ordenar por:

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

Pueden agregar esto al modelo para tener una estructura de prueba ya configurada al crear clintes: ```python class CustomerCreate(CustomerBase): pass class Config: json_schema_extra = { "example": { "name": "JimcostDev", "description": "Developer", "email": "[email protected]", "age": 25 } } ```
Mi solución: Actualiza Customer. ![](https://static.platzi.com/media/user_upload/imagen-f9b7f9dd-d509-4e7d-a1e6-7b9d8ed706f0.jpg)
SI les da error en el import del HTTPException desde fastapi puende importar desde starlette.exceptions from starlette.exceptions import HTTPException
![](https://static.platzi.com/media/user_upload/image-9633e89d-a5bc-4338-8480-88eaa204f869.jpg)
Edición de Customer ```js @app.put("/customers/{id}", response_model=Customer) async def update_customer(id: int, customer_data: CustomerCreate, session: SessionDep) -> Customer: customer = session.get(Customer, id) if not customer: raise HTTPException(status_code=404, detail="Customer not found") update_data = customer_data.model_dump(exclude_unset=True) customer.sqlmodel_update(update_data) session.add(customer) session.commit() session.refresh(customer) return customer ```@app.put("/customers/{id}", response\_model=Customer)async def update\_customer(id: int, customer\_data: CustomerCreate, session: SessionDep) -> Customer:    customer = session.get(Customer, id)    if not customer:        raise HTTPException(status\_code=404, detail="Customer not found")    update\_data = customer\_data.model\_dump(exclude\_unset=True)    customer.sqlmodel\_update(update\_data)    session.add(customer)    session.commit()    session.refresh(customer)    return customer
@app.get("/customers/{id}")async def list\_customer(id: int, session: SessionDep): return session.get(Customer, id)
Tengo la duda sobre si al momento de realizar endpoint para actualizar registros debemos de usar put o patch y si se debe de enviar solo la columnas que desean actualizar o si deben de enviar todos los datos que componen la tabla?
Este código demuestra cómo manejar la funcionalidad de eliminación en un CRUD básico con FastAPI y SQLModel. Puedes integrar esta funcionalidad con las operaciones de creación, lectura y actualización para construir una API completa y funcional
Comparto mi solución: ```python @app.put("/customers/{id}") async def update_customer(id: int, CustomerData: CustomerCreate, session: SessionDep): customer_id = session.get(Customer, id) if not customer_id: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Customer does not exist") if customer_id: if CustomerData.name: customer_id.name = CustomerData.name if CustomerData.description: customer_id.description = CustomerData.description if CustomerData.email: customer_id.email = CustomerData.email if CustomerData.age: customer_id.age = CustomerData.age session.add(customer_id) session.commit() session.refresh(customer_id) return {"detail": "ok, updated"} ```
`@app.put("/customers/{customer_id}", response_model=Customer)` `async def update_customer(customer_id: int, customer_data: CustomerCreate, session: SessionDep):` `customer = session.get(Customer, customer_id)` `customer.name = customer_data.name` `customer.description = customer_data.description` `customer.email = customer_data.email` `customer.age = customer_data.age` `session.add(customer)` `session.commit()` `session.refresh(customer)` `return customer`
Endpoint para actualizar el Customer:@app.put("/customers/{customer\_id}", response\_model=Customer)def update\_customer( session: SessionDep, customer\_id: int, customer\_data: CustomerUpdate) -> Customer: customer = session.get(Customer, customer\_id) if not customer: raise HTTPException( status\_code=status.HTTP\_404\_NOT\_FOUND, detail="Customer not found" ) customer\_update\_data = customer\_data.model\_dump(exclude\_unset=True) customer.sqlmodel\_update(customer\_update\_data) session.add(customer) session.commit() session.refresh(customer) return customer ```python @app.put("/customers/{customer_id}", response_model=Customer) def update_customer( session: SessionDep, customer_id: int, customer_data: CustomerUpdate ) -> Customer: customer = session.get(Customer, customer_id) if not customer: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Customer not found" ) customer_update_data = customer_data.model_dump(exclude_unset=True) customer.sqlmodel_update(customer_update_data) session.add(customer) session.commit() session.refresh(customer) return customer ```
Para este ejercicio he utilizado el método patch para modificar un registro existente en la BD: @app.patch("/customers/{id}", response\_model=Customer)async def update\_customer(id: int, data: CustomerUpdate, session: SessionDep): customer = session.get(Customer, id) if not customer: raise HTTPException( status\_code=status.HTTP\_404\_NOT\_FOUND, detail="Customer does not exist" ) update\_data = data.model\_dump(exclude\_unset=True) try: CustomerUpdate.model\_validate(update\_data) except ValidationError as e: raise HTTPException( status\_code=status.HTTP\_422\_UNPROCESSABLE\_ENTITY, detail=str(e) ) customer.sqlmodel\_update(update\_data) session.add(customer) session.commit() session.refresh(customer) return customer También he creado un nuevo modelo (CustomerUpdate), con definiendo los campos como opcionales y dandoles un valor por defecto de None para evitar un fallo en la validación cuando se actualiza parcialmente el registro: class CustomerUpdate(BaseModel): name: Optional\[str] = None description: Optional\[str] = None age: Optional\[int] = None
```python @app.put("/customers/{customer_id}", response_model=Customer) async def update_customer(customer_id: int, customer_data: CustomerCreate, session: SessionDep): """Update a customer by ID.""" customer_db = session.get(Customer, customer_id) if not customer_db: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Customer not found") customer_db.model_validate(customer_data.model_dump()) session.commit() session.refresh(customer_db) return customer_db ```