SQLModel 开发笔记:Python SQL 数据库操作的「简化神器」

作为一名常年和 Python 后端打交道的开发者,最近在 FastAPI 项目中发现了一款宝藏库 ------SQLModel。它完美融合了 Pydantic 的类型校验和 SQLAlchemy 的数据库交互能力,直接解决了我之前「重复定义模型」的痛点。今天就从 PyPI 页面信息出发,整理一份超实用的开发笔记,帮大家快速上手!

一、先搞懂:SQLModel 是什么?

简单来说,SQLModel 是一款专为 Python 设计的 SQL 数据库操作库,核心定位是「简化 SQL 交互,同时兼容主流生态」。它由 FastAPI 作者 tiangolo 开发,底层基于 Pydantic(类型注解)和 SQLAlchemy(数据库 ORM),尤其适合 FastAPI 项目,但也能独立用于各类 Python 应用。

关键基础信息(必看)

类别 详情
最新版本 0.0.25(2025-09-18 发布,更新频率稳定)
支持 Python 版本 3.8~3.13(仅 Python 3,无 Python 2 兼容)
安装命令 pip install sqlmodel(自动安装 Pydantic、SQLAlchemy 依赖)
开发阶段 Beta(4 - Beta),功能稳定,适合生产环境试用
许可证 MIT(开源免费,可商用)

二、核心优势:为什么选 SQLModel?

用过 SQLAlchemy 和 Pydantic 的同学都知道,之前要分别定义「数据库模型」和「接口校验模型」,代码重复率极高。而 SQLModel 完美解决了这个问题,核心优势总结为 4 点:

1. 「一份代码,两种身份」:少写重复代码

定义一个 SQLModel 类,它同时是:

  • SQLAlchemy 模型(可直接操作数据库)
  • Pydantic 模型(可直接用于接口参数校验、序列化)
    比如定义一个Hero模型,既可以用它查数据库,也能直接作为 FastAPI 接口的请求 / 响应模型,无需重复写两遍。

2. 极致的编辑器支持:写代码不查文档

作为强类型库,SQLModel 天生支持:

  • 全场景自动补全(字段名、方法名、查询条件都能补)
  • 实时 Inline 错误提示(类型不匹配、字段缺失直接标红)
  • 跳转定义(点击字段能直接到模型定义处)
    对我这种「记不住 API」的开发者太友好了,写代码效率至少提升 30%。

3. 无缝兼容生态:不绑架你的技术栈

  • 兼容 FastAPI:直接作为接口模型,无需额外转换
  • 兼容 SQLAlchemy:可与现有 SQLAlchemy 模型混用,支持 SQLAlchemy 的所有查询语法
  • 兼容 AsyncIO:支持异步数据库操作,适合高并发场景
    也就是说,即使你现有项目用的是 SQLAlchemy,也能平滑迁移到 SQLModel,不用重构整个项目。

4. 极简 API:新手也能快速上手

默认配置合理,无需复杂初始化。比如创建数据库连接、定义表结构、增删改查,代码都比原生 SQLAlchemy 简洁很多,新手看文档 10 分钟就能写出可用代码。

三、实操案例:从 0 到 1 用 SQLModel 操作数据库

光说不练假把式,这里用一个「英雄管理」的案例,带大家快速掌握 SQLModel 的核心用法(基于最新版 0.0.25)。

1. 第一步:定义数据库模型

先定义一个Hero模型,对应数据库中的hero表,包含id(主键)、name(姓名)、secret_name(秘密身份)、age(年龄,可选)四个字段:

python 复制代码
from sqlmodel import Field, SQLModel
# 注意:table=True表示这是一个数据库表模型
    
class Hero(SQLModel, table=True):
    # 主键:默认None,插入数据库时自动生成
    id: int | None = Field(default=None, primary_key=True)
    # 必选字段:str类型,不允许为None
    name: str
    secret_name: str
    # 可选字段:int类型,允许为None
    age: int | None = None

2. 第二步:初始化数据库连接

create_engine创建数据库引擎(这里以 SQLite 为例,无需额外安装数据库;如果用 MySQL/PostgreSQL,只需改连接字符串):

python 复制代码
from sqlmodel import create_engine

# SQLite数据库:数据库文件会保存在当前目录下的database.db
engine = create_engine("sqlite:///database.db")
# 关键:创建所有定义的表(如果表不存在)
SQLModel.metadata.create_all(engine)

3. 第三步:增删改查操作

SQLModel 通过Session管理数据库会话,所有操作都在会话中进行,用完自动关闭(推荐用with语句)。

(1)新增数据(插入)
python 复制代码
from sqlmodel import Session
# 1. 创建要插入的数据(实例化Hero模型)
hero1 = Hero(name="Deadpond", secret_name="Dive Wilson")
hero2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
hero3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
# 2. 插入数据库
with Session(engine) as session:
    # 添加数据到会话
    session.add(hero1)
    session.add(hero2)
    session.add(hero3)
    # 提交会话(必须提交,否则数据不会写入数据库)
    session.commit()
    # 可选:刷新数据,获取数据库自动生成的id
    session.refresh(hero1)
    print(f"插入成功,hero1的id是:{hero1.id}")
(2)查询数据

支持 SQLAlchemy 的所有查询语法,这里举几个常用场景:

python 复制代码
from sqlmodel import select

with Session(engine) as session:
    # 场景1:查询所有数据
    statement = select(Hero)
    heroes = session.exec(statement).all()  # all()获取所有结果
    print("所有英雄:", heroes)
    # 场景2:按条件查询(比如查name="Spider-Boy"的英雄)
    statement = select(Hero).where(Hero.name == "Spider-Boy")
    hero = session.exec(statement).first()  # first()获取第一条结果
    print("Spider-Boy:", hero)
    # 场景3:按主键查询(更高效)
    hero = session.get(Hero, 1)  # 获取id=1的英雄
    print("id=1的英雄:", hero)
(3)更新数据
python 复制代码
with Session(engine) as session:
    # 1. 先查询要更新的数据
    hero = session.get(Hero, 3)  # 获取id=3的Rusty-Man
    if hero:
        # 2. 修改字段值
        hero.age = 49
        # 3. 提交会话(自动更新)
        session.commit()
        print("更新后:", hero)
(4)删除数据
python 复制代码
with Session(engine) as session:
    # 1. 先查询要删除的数据
    hero = session.get(Hero, 1)  # 获取id=1的Deadpond
    if hero:
        # 2. 删除数据
        session.delete(hero)
        # 3. 提交会话
        session.commit()
        print("删除成功")

4. 第四步:结合 FastAPI 使用

如果你的项目是 FastAPI,SQLModel 的优势会更明显 ------ 直接用模型作为接口参数 / 响应:

python 复制代码
from fastapi import FastAPI
from sqlmodel import Session, select
app = FastAPI()
# 接口1:新增英雄(请求体直接用Hero模型)
@app.post("/heroes/")
def create_hero(hero: Hero):
    with Session(engine) as session:
        session.add(hero)
        session.commit()
        session.refresh(hero)
        return hero
# 接口2:查询所有英雄(响应直接返回Hero列表)
@app.get("/heroes/")
def get_heroes():
    with Session(engine) as session:
        heroes = session.exec(select(Hero)).all()
        return heroes

启动 FastAPI 后,访问/docs就能看到自动生成的接口文档,参数校验、类型提示全都是现成的,这体验谁用谁知道!

四、实用资源汇总(收藏不迷路)

  1. 官方文档https://sqlmodel.tiangolo.com(最权威,含完整教程)
  2. 源码仓库https://github.com/fastapi/sqlmodel(Star 16.8k+,issues 响应快)3. 问题反馈:GitHub Issues(优先用英文提问,作者响应及时)
  3. Changelog:查看版本更新记录(避免升级踩坑)
  4. 兼容注意事项
    • 如果你用 SQLAlchemy 2.0+,SQLModel 完全兼容
    • 如果需要异步操作,需安装sqlalchemy[asyncio],并使用AsyncSession

五、个人使用心得

  1. 适合场景:FastAPI 项目、需要类型校验的数据库操作、不想写重复模型的场景
  2. 避坑提醒
    • 定义模型时,table=True必须加,否则无法映射到数据库表
    • 会话操作必须commit(),否则数据不会持久化
    • Python 版本必须≥3.8,否则安装会报错
  3. 对比选择
    • 如果你需要极致简洁 + FastAPI 兼容:选 SQLModel
    • 如果你需要更复杂的数据库特性(如存储过程):直接用 SQLAlchemy
    • 如果你用 Django:Django ORM 更适配,无需额外用 SQLModel

最后说一句:SQLModel 虽然处于 Beta 阶段,但功能已经很稳定,我在生产环境用了半年多,没遇到过重大 bug。如果你也被「重复定义模型」困扰,强烈建议试试!

相关推荐
NGINX开源社区6 分钟前
使用 Microsoft Entra ID 配置 NGINX Plus 以实现 SAML SSO
后端·python·flask
小鸡吃米…9 分钟前
基于 TensorFlow 的图像识别
人工智能·python·tensorflow
西门吹雪分身13 分钟前
mysql之数据离线迁移
数据库·mysql
儒雅芝士21 分钟前
RethinkFun深度学习笔记
人工智能·笔记·深度学习
小鸡吃米…31 分钟前
TensorFlow - 构建计算图
人工智能·python·tensorflow
土拨鼠烧电路39 分钟前
笔记12:AI在快消:超越概念的四大落地场景
人工智能·笔记
电商API&Tina1 小时前
京东商品详情API接口接入与应用
数据库·microsoft
cipher1 小时前
crawl4ai:AI时代的数据采集利器——从入门到实战
后端·爬虫·python
OnYoung1 小时前
理解关系数据库表间的一对一和一对多关系
数据库
南 阳1 小时前
Python从入门到精通day37
数据库·python·oracle