共计 1618 个字符,预计需要花费 5 分钟才能阅读完成。
在实际开发中,数据库模型往往存在相似的字段和逻辑。如果每个模型都重复编写相同的代码,不仅冗余,还容易出错。SQLModel 支持通过继承和封装来优化代码结构,提高可维护性。
一、模型继承的基本用法
假设我们有多个表,它们都包含 id、created_at 和 updated_at 字段。我们可以先定义一个基础模型:
from datetime import datetime
from sqlmodel import SQLModel, Field
class BaseModel(SQLModel):
id: int | None = Field(default=None, primary_key=True)
created_at: datetime = Field(default_factory=datetime.utcnow, nullable=False)
updated_at: datetime = Field(default_factory=datetime.utcnow, nullable=False)
然后让其他模型继承 BaseModel:
class User(BaseModel, table=True):
name: str
email: str
class Post(BaseModel, table=True):
title: str
content: str
user_id: int
这样,User 和 Post 就自动拥有 id 和时间字段,不需要重复书写。
二、在继承模型中使用表配置
有时我们需要为不同的模型设置单独的表名,可以通过 table=True 和 __tablename__ 属性实现:
class User(BaseModel, table=True):
__tablename__ = "users"
name: str
email: str
这样继承既保持了统一的字段,又能单独控制表名。
三、通用查询封装
在日常开发中,常见的操作包括根据 ID 查询、获取所有记录、分页查询等。我们可以通过封装通用的数据库操作类,减少重复:
from sqlmodel import Session, select
class CRUDBase:
def __init__(self, model):
self.model = model
def get(self, session: Session, id: int):
return session.get(self.model, id)
def get_all(self, session: Session):
statement = select(self.model)
return session.exec(statement).all()
def create(self, session: Session, obj):
session.add(obj)
session.commit()
session.refresh(obj)
return obj
def delete(self, session: Session, id: int):
obj = session.get(self.model, id)
if obj:
session.delete(obj)
session.commit()
return obj
使用时只需传入具体模型:
user_crud = CRUDBase(User)
post_crud = CRUDBase(Post)
with Session(engine) as session:
new_user = User(name="Alice", email="[email protected]")
user_crud.create(session, new_user)
users = user_crud.get_all(session)
print(users)
四、小结
通过继承 BaseModel,我们可以在多个模型中共享公共字段。结合通用查询类的封装,不仅减少了重复代码,还让项目结构更清晰,更容易维护。
下一节我们将学习如何在 SQLModel 中实现事务管理,保证复杂操作的数据一致性与可靠性。
正文完