Skip to content

Unify SQLAlchemy schemas and Pydantic models using SQLModel #173

@nanotaboada

Description

@nanotaboada
Owner

Description

The application currently defines football player models in two layers:

  • schemas/player_schema.py (SQLAlchemy ORM class used for DB operations)
  • models/player_model.py (Pydantic model for request/response validation)

This results in:

  • Duplicated attributes across files
  • Maintenance overhead when the schema evolves
  • Redundant translation logic between SQLAlchemy and Pydantic

Proposed Solution

Introduce SQLModel to consolidate the Player ORM and data validation layers. SQLModel extends both SQLAlchemy and Pydantic, allowing a single class to serve as:

  • The ORM model for database operations
  • The Pydantic model for validation and OpenAPI docs

This will simplify the model architecture while preserving existing behavior.

Suggested Approach

  1. Install SQLModel
pip install sqlmodel
  1. Create a new SQLModel-based class in models/player_model.py (or optionally models/player_sqlmodel.py during migration):
from typing import Optional
from sqlmodel import SQLModel, Field

class Player(SQLModel, table=True):
    __tablename__ = "players"

    id: Optional[int] = Field(default=None, primary_key=True)
    first_name: str = Field(alias="firstName")
    middle_name: Optional[str] = Field(default=None, alias="middleName")
    last_name: str = Field(alias="lastName")
    date_of_birth: Optional[str] = Field(default=None, alias="dateOfBirth")
    squad_number: int = Field(alias="squadNumber", unique=True)
    position: str
    abbr_position: Optional[str] = Field(default=None, alias="abbrPosition")
    team: Optional[str] = None
    league: Optional[str] = None
    starting11: Optional[bool] = None

Note: Field(..., alias="camelCaseName") preserves existing naming and OpenAPI compatibility.

  1. Update route handlers and services to use Player from SQLModel directly for both DB and validation.

  2. Remove the old Player class from schemas/player_schema.py and PlayerModel from models/player_model.py.

  3. Update tests and factories/stubs to use the new unified model.

Acceptance Criteria

  • A single Player class using SQLModel represents both DB schema and API schema
  • Redundant Pydantic and SQLAlchemy Player models are removed
  • Database CRUD operations continue to function
  • FastAPI auto-generates OpenAPI docs from SQLModel model as expected
  • CamelCase field naming preserved in OpenAPI and response payloads
  • Existing integration tests pass without regressions
  • Models are still serializable and validate inputs correctly

Activity

changed the title [-]Consider implementing SQLModel[/-] [+]Consider SQLModel to consolidate Pydantic models with SQLAlchemy schemas[/+] on Aug 1, 2024
self-assigned this
on Aug 1, 2024
pinned this issue on Aug 2, 2024
removed their assignment
on Aug 2, 2024
unpinned this issue on Mar 29, 2025
pinned this issue on Mar 29, 2025
unpinned this issue on May 28, 2025
pinned this issue on Jun 1, 2025
changed the title [-]Consider SQLModel to consolidate Pydantic models with SQLAlchemy schemas[/-] [+]Unify SQLAlchemy schemas and Pydantic models using SQLModel[/+] on Jun 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpythonPull requests that update Python code

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @nanotaboada

        Issue actions

          Unify SQLAlchemy schemas and Pydantic models using SQLModel · Issue #173 · nanotaboada/python-samples-fastapi-restful