Skip to content

Refactor entity defintions for SQLModel and FastAPI Response #35

@vredchenko

Description

@vredchenko

Yes, it's definitely possible to use inheritance to manage both the SQLModel definition and the FastAPI response model from a single source of truth. This approach can help reduce code duplication and make it easier to maintain consistency between your database model and API response.

Here's how you can refactor your code to achieve this:

from sqlmodel import SQLModel, Field, Relationship
from pydantic import BaseModel
from typing import Optional, List
from datetime import datetime
from sqlalchemy import Column

class GridBase(SQLModel):
    status: GridStatus = Field(default=GridStatus.NONE)
    name: str
    scan_start_time: Optional[datetime] = Field(default=None)
    scan_end_time: Optional[datetime] = Field(default=None)

class Grid(GridBase, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    session_id: Optional[int] = Field(default=None, foreign_key="session.id")
    status: GridStatus = Field(default=GridStatus.NONE, sa_column=Column(GridStatusType()))
    
    session: Optional[Session] = Relationship(back_populates="grids")
    gridsquares: List["GridSquare"] = Relationship(back_populates="grid", cascade_delete=True)

class GridResponse(GridBase):
    id: int
    session_id: Optional[int]

    class Config:
        from_attributes = True

In this refactored version:

  1. We create a GridBase class that contains the common fields between the SQLModel and the response model.

  2. The Grid class inherits from GridBase and adds the database-specific fields and relationships.

  3. The GridResponse class also inherits from GridBase and adds the id and session_id fields that are specific to the response.

This approach allows you to maintain a single source of truth for the common fields in GridBase, while still having the flexibility to add database-specific or response-specific fields in the respective classes.

Note that we keep the sa_column=Column(GridStatusType()) in the Grid class because it's specific to the SQLAlchemy configuration and not needed in the response model.

This structure makes it easier to keep your database model and API response in sync, as any changes to the common fields can be made in the GridBase class and will be reflected in both the Grid and GridResponse classes.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions