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。如果你也被「重复定义模型」困扰,强烈建议试试!

相关推荐
三个人工作室2 小时前
mysql允许所有ip地址访问,mysql允许该用户访问自己的数据库【伸手党福利】
数据库·tcp/ip·mysql
QQ828929QQ2 小时前
MySQL Explain 分析 SQL 执行计划
数据库·sql·mysql
曲幽2 小时前
FastAPI生命周期管理实战:从启动到关闭,如何优雅地管好你的“资源家当”
redis·python·fastapi·web·shutdown·startup·lifespan
我是小超人-雨石花2 小时前
postgresql + postgis安装
数据库·postgresql·postgis·空间数据库
码农很忙2 小时前
SCALE发布《2025年12月大模型SQL能力排行榜》:格局与趋势洞察
数据库·业界资讯
gr17852 小时前
通过dify文件上传能力,解决较大文本与LLM实时交互问题
python·llm·aigc·dify
放弃 治疗2 小时前
Windows 11 系统 Oracle PLSQL 工具(PL/SQL Developer 最新版本)完整安装与配置教程
数据库·sql
IvanCodes2 小时前
openGauss 实战手册:gsql 常用命令、认证配置与运维工具全解
大数据·数据库·sql·opengauss
学习的周周啊2 小时前
ClawdBot(openclaw) + Cloudflare Tunnel + Zero-Trust 零基础保姆教程
网络·人工智能·python·clawdbot