Pydantic is a Python library that provides runtime type checking and validation of data. Let me explain how validation works with simple examples.
Basic Example Without ORM
First, let's look at a simple Pydantic model without database/ORM involvement:
from pydantic import BaseModel
class Person(BaseModel):
    name: str
    age: int
# Valid input (dictionary)
valid_data = {"name": "Alice", "age": 30}
person = Person(**valid_data)  # or Person.model_validate(valid_data)
print(person)  # Works fine
# Invalid input
invalid_data = {"name": "Bob", "age": "thirty"}  # age should be int
try:
    person = Person(**invalid_data)
except Exception as e:
    print(f"Error: {e}")  # Shows validation error for age
The Problem With ORM Objects
When working with SQLAlchemy ORM models, we can't directly use them with Pydantic because:
# SQLAlchemy model
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String)
# Pydantic model
class UserResponse(BaseModel):
    id: int
    name: str
# This WON'T work directly:
db_user = User(id=1, name="Alice")
try:
    response = UserResponse.model_validate(db_user)
except Exception as e:
    print(f"Error: {e}")  # Fails because Pydantic doesn't know how to handle ORM objects
  
  
  Solution: from_attributes=True
This is where from_attributes=True comes in. It tells Pydantic:
- "When I give you an ORM object, don't treat it as a dictionary"
- "Instead, access its attributes directly (like db_user.id,db_user.name)"
class UserResponse(BaseModel):
    id: int
    name: str
    class Config:
        from_attributes = True  # Previously called orm_mode=True
# Now this WORKS:
db_user = User(id=1, name="Alice")
response = UserResponse.model_validate(db_user)
print(response)  # UserResponse(id=1, name='Alice')
How It Works Step-by-Step
- 
You pass an ORM object to model_validate()
- 
Pydantic checks from_attributesin the Config
- 
Instead of treating it as a dict, Pydantic:
- Looks at the field names in your Pydantic model (id,name)
- Tries to access those attributes on the ORM object (db_user.id,db_user.name)
- Validates the values it finds
 
- Looks at the field names in your Pydantic model (
Real-world Example
Your WorkHistoryResponse should be:
class WorkHistoryResponse(BaseModel):
    id: int
    user_id: int
    facility_name: str
    # ... other fields ...
    class Config:
        from_attributes = True  # This enables ORM model conversion
Then when you do:
WorkHistoryResponse.model_validate(work_history_orm_object)
Pydantic will:
- See from_attributes=True
- Look for work_history_orm_object.id
- Look for work_history_orm_object.user_id
- Look for work_history_orm_object.facility_name
- And so on for all fields in response model
Key Takeaways
- Direct dictionaries work automatically with Pydantic
- 
ORM objects need from_attributes=Trueto be validated
- The Config class must be inside your Pydantic model
- Field names must match between your ORM model and Pydantic model
 

 
    
Top comments (0)