First Check
Commit to Help
Example Code
from typing import Optional, Union
from fastapi import FastAPI, Depends, HTTPException
from sqlmodel import Field, Session, SQLModel, create_engine, select
class ActiveRecord(SQLModel):
@classmethod
def by_id(cls, id: int, session):
obj = session.get(cls, id)
if obj is None:
raise HTTPException(status_code=404, detail=f"{cls.__name__} with id {id} not found")
return obj
@classmethod
def all(cls, session):
return session.exec(select(cls)).all()
@classmethod
def create(cls, source: Union[dict, SQLModel], session):
if isinstance(source, SQLModel):
obj = cls.from_orm(source)
elif isinstance(source, dict):
obj = cls.parse_obj(source)
session.add(obj)
session.commit()
session.refresh(obj)
return obj
def save(self, session):
session.add(self)
session.commit()
session.refresh(self)
def update(self, source: Union[dict, SQLModel], session):
if isinstance(source, SQLModel):
source = source.dict(exclude_unset=True)
for key, value in source.items():
setattr(self, key, value)
self.save(session)
def delete(self, session):
session.delete(self)
session.commit()
class HeroBase(SQLModel):
name: str = Field(index=True)
secret_name: str
age: Optional[int] = Field(default=None, index=True)
class HeroCreate(HeroBase):
pass
class HeroRead(HeroBase):
id: int
class HeroUpdate(SQLModel):
name: Optional[str] = None
secret_name: Optional[str] = None
age: Optional[int] = None
class Hero(HeroBase, ActiveRecord, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"
connect_args = {"check_same_thread": False}
engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
def create_db_and_tables():
SQLModel.metadata.create_all(engine)
def get_session():
with Session(engine) as session:
yield session
app = FastAPI()
@app.on_event("startup")
def on_startup():
create_db_and_tables()
@app.post("/heroes/", response_model=HeroRead)
def create_hero(hero: HeroCreate, session: Session = Depends(get_session)):
return Hero.create(hero, session)
@app.get("/heroes/", response_model=list[HeroRead])
def read_heroes(session: Session = Depends(get_session)):
return Hero.all(session)
@app.get("/heroes/{id}", response_model=HeroRead)
def read_heroes(id: int, session: Session = Depends(get_session)):
return Hero.by_id(id, session)
@app.patch("/heroes/{id}", response_model=HeroRead)
def read_heroes(id: int, hero: HeroUpdate, session: Session = Depends(get_session)):
db_hero = Hero.by_id(id, session)
db_hero.update(hero, session)
return db_hero
Description
Hi all,
I'm fairly new to FastAPI and SQLModel, but I really like these libraries. After porting two Flask+SQLAlchemy projects to FastAPI+SQLModel, I noticed that I write lots of boilerplate code to implement basic model functions like create, save, delete or update. I was surprised that the examples in the documentation implement CRUD functionality with functions rather than member functions of the models.
So I wrote a class called ActiveRecord to be used as a mixin for SQLModel classes, which adds these functions and can be reused for different models and projects. In my code above you see it being used with the multi-model Hero example in the documentation, which shortens the remaining code (compare https://sqlmodel.tiangolo.com/tutorial/fastapi/multiple-models)
Using something like this in all of my SQLModel classes where table=True seems so obvious, that I suspect that there's either something I'm missing here, or this is functionality that's really missing in SQLModel. Why doesn't the SQLModel class have such functions? How do you do that? Do you think this is worth contributing? I guess, at least I could clean it up and share it as gist.
Thanks for any feedback,
Boris
Operating System
macOS
Operating System Details
No response
SQLModel Version
0.0.6
Python Version
3.9.5
Additional Context
No response
First Check
Commit to Help
Example Code
Description
Hi all,
I'm fairly new to FastAPI and SQLModel, but I really like these libraries. After porting two Flask+SQLAlchemy projects to FastAPI+SQLModel, I noticed that I write lots of boilerplate code to implement basic model functions like create, save, delete or update. I was surprised that the examples in the documentation implement CRUD functionality with functions rather than member functions of the models.
So I wrote a class called ActiveRecord to be used as a mixin for SQLModel classes, which adds these functions and can be reused for different models and projects. In my code above you see it being used with the multi-model Hero example in the documentation, which shortens the remaining code (compare https://sqlmodel.tiangolo.com/tutorial/fastapi/multiple-models)
Using something like this in all of my SQLModel classes where table=True seems so obvious, that I suspect that there's either something I'm missing here, or this is functionality that's really missing in SQLModel. Why doesn't the SQLModel class have such functions? How do you do that? Do you think this is worth contributing? I guess, at least I could clean it up and share it as gist.
Thanks for any feedback,
Boris
Operating System
macOS
Operating System Details
No response
SQLModel Version
0.0.6
Python Version
3.9.5
Additional Context
No response