Consultar pagos con filtros seguros
Objetivos
Vas a leer pagos Sakila con parámetros acotados y expresiones SQLAlchemy que conservan una fila por pago.
Concepto
Un filtro reduce qué filas devuelve una consulta. Una API puede recibir valores como staff_id o un importe mínimo, validarlos como números y añadir condiciones con select() y .where(). SQLAlchemy enlaza esos valores como parámetros; la persona que llama no puede sustituirlos por una frase SQL.
El modelo Payment representa columnas que existen en sakila.payment. La clave primaria payment_id identifica cada pago. El importe usa Numeric(5, 2) y la fecha una marca temporal. En la respuesta solo incluimos cuatro campos y el endpoint tiene paginación.
Ejemplo
Añade el modelo en app/models.py:
from datetime import datetime
from decimal import Decimal
from sqlalchemy import DateTime, Integer, Numeric
from sqlalchemy.orm import Mapped, mapped_column
class Payment(Base):
__tablename__ = "payment"
payment_id: Mapped[int] = mapped_column(Integer, primary_key=True)
payment_date: Mapped[datetime] = mapped_column(DateTime)
amount: Mapped[Decimal] = mapped_column(Numeric(5, 2))
staff_id: Mapped[int] = mapped_column(Integer)Declara PaymentOut con esos campos y from_attributes=True. La consulta en app/main.py puede combinar los filtros:
statement = select(Payment)
if staff_id is not None:
statement = statement.where(Payment.staff_id == staff_id)
if min_amount is not None:
statement = statement.where(Payment.amount >= min_amount)
if max_amount is not None:
statement = statement.where(Payment.amount <= max_amount)
rows = db.scalars(
statement.order_by(Payment.payment_id).limit(limit).offset(offset)
).all()Define staff_id como entero positivo; min_amount y max_amount como decimales entre 0 y 999.99; limita limit a 50. Los parámetros de consulta son valores, nunca texto SQL. El diccionario Sakila documenta payment_id, payment_date, amount y staff_id.
Práctica guiada
- Solicita pagos con
staff_id=1y revisa la columnastaff_idde cada fila. - Añade un importe mínimo y comprueba que ninguno quede por debajo.
- Cambia el límite y confirma que
payment_idsigue ordenando el resultado.
Reto
Completa una ruta GET /payments con limit entre 1 y 50, offset no negativo y staff_id opcional. No aceptes SQL como un parámetro de la ruta.
Intenta el reto antes de consultar las pistas.
Quiz
Comprobación
Los filtros usan columnas y valores tipados. Después resumirás pagos por staff sin perder de vista qué representa cada grupo.