Contenido del curso
Parámetros y Validación
CRUD en FastAPI
Arquitectura en FastAPI
Bases de Datos y Consultas
Middlewares
Unit Testing
Seguridad y Autenticación
Validar emails únicos con Pydantic y FastAPI
Resumen
La validación de datos en FastAPI va mucho más allá de comprobar tipos básicos como string o entero. Con Pydantic puedes verificar formatos específicos como un email válido y, además, consultar la base de datos para asegurar que un valor sea único. Esto es clave para cualquier desarrollador backend que quiera mantener la integridad de los datos según la lógica de negocio.
¿Cómo validar un email con EmailStr en Pydantic?
Pydantic incluye tipos predefinidos que se encargan de validaciones comunes sin que tengas que escribir lógica adicional. Uno de los más útiles es EmailStr, que comprueba que el valor tenga formato de correo electrónico, con arroba y dominio.
Para usarlo, abres tu archivo models.py y añades el import desde Pydantic. Luego, en tu modelo Customer, cambias el tipo del campo email de str a EmailStr. Con ese pequeño ajuste, FastAPI rechazará cualquier email mal formado y devolverá un ValueError indicando que el valor no es válido.
¿Qué hace EmailStr en Pydantic? Valida automáticamente que un campo tenga formato de email: contenga arroba y un dominio al final. Si el valor no cumple, Pydantic lanza un error antes de que el dato llegue a tu lógica.
Si pruebas el endpoint de crear customers con un email inválido, recibirás un mensaje claro en body.email. Al pasar uno válido, la creación funciona sin problemas [01:00].
¿Cómo crear validaciones personalizadas con field_validator?
Validar el formato no siempre alcanza. En muchos casos necesitas reglas que dependen de tu base de datos, como evitar emails duplicados. Aquí entra el decorador field_validator de Pydantic v2.
En versiones anteriores se usaba validator, pero ese decorador está deprecado. La documentación de FastAPI marca esa línea como obsoleta y sugiere migrar a field_validator, que es la forma actual de declarar validaciones personalizadas en Pydantic 2 [01:55].
¿Cómo se estructura un field_validator?
Dentro del modelo creas un método, por ejemplo validate_email, y lo decoras con @field_validator("email") indicando el campo o campos a validar. La función recibe dos argumentos: cls y value, y debe retornar el valor ya validado.
Un detalle importante: field_validator solo se aplica a métodos de instancia tratados como class methods. Por eso, en lugar de self usas cls y agregas el decorador @classmethod encima. Sin ese ajuste, la aplicación lanza un error y no arranca.
python from pydantic import EmailStr, field_validator from sqlmodel import Session, select from db import engine
class Customer(SQLModel): email: EmailStr
@field_validator("email") @classmethod def validate_email(cls, value): session = Session(engine) query = select(Customer).where(Customer.email == value) result = session.exec(query).first() if result: raise ValueError("this email is already registered") return value
¿Cómo validar que un email sea único contra la base de datos?
La lógica dentro del validador conecta tu modelo con la base de datos. Para eso necesitas tres piezas: la clase Session desde sqlmodel, el engine ya creado en tu archivo db, y la función select para construir la consulta.
La consulta es directa: seleccionas de la tabla Customer con una cláusula where que compara el campo email con el valor recibido. Ejecutas la query con session.exec(query).first(), que devuelve el primer resultado o None si no hay coincidencias.
- Si
resulttiene un valor, significa que ya existe un usuario con ese correo y lanzasraise ValueError("this email is already registered"). - Si
resultesNone, retornasvaluey la creación continúa con normalidad. - Esta misma estructura sirve para validar cualquier campo contra cualquier tabla, no solo emails.
¿Cuándo usar field_validator en lugar de un constraint unique? Úsalo cuando necesites lógica personalizada o validar contra varias tablas. Para unicidad simple, un
unique=Trueen el campo es más eficiente, perofield_validatorte da control total sobre el mensaje y el flujo.
Al probar el endpoint con un correo ya registrado, FastAPI responde con un error en body.email indicando que el email está registrado. Esa respuesta se construye automáticamente a partir del ValueError que lanzaste dentro del validador [04:30].
¿Por qué importa validar más allá de los tipos?
Validar tipos protege tu API de inputs malformados, pero la integridad real de tus datos depende de reglas de negocio. Un email único, un rango de fechas coherente o un identificador que exista en otra tabla son validaciones que solo tú puedes definir.
Con EmailStr cubres el formato. Con field_validator y una sesión activa cubres cualquier regla que requiera consultar tu base de datos. La combinación te permite construir modelos que rechazan datos inválidos antes de que toquen tu capa de servicio.
Ahora te toca a ti: agrega más validadores en tus modelos, prueba con otros campos como teléfono o documento de identidad, y comparte tus implementaciones en los comentarios.