惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Archives - TechRepublic
Security Archives - TechRepublic
Project Zero
Project Zero
K
Kaspersky official blog
G
Google Developers Blog
T
Threat Research - Cisco Blogs
T
The Blog of Author Tim Ferriss
Cyberwarzone
Cyberwarzone
Y
Y Combinator Blog
Recorded Future
Recorded Future
Blog — PlanetScale
Blog — PlanetScale
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Cisco Talos Blog
Cisco Talos Blog
Latest news
Latest news
Microsoft Security Blog
Microsoft Security Blog
H
Help Net Security
S
Schneier on Security
P
Palo Alto Networks Blog
H
Hacker News: Front Page
N
News and Events Feed by Topic
N
Netflix TechBlog - Medium
博客园 - Franky
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
SecWiki News
SecWiki News
Cloudbric
Cloudbric
TaoSecurity Blog
TaoSecurity Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The Hacker News
The Hacker News
C
Check Point Blog
L
LangChain Blog
腾讯CDC
小众软件
小众软件
T
Tenable Blog
Google DeepMind News
Google DeepMind News
GbyAI
GbyAI
L
LINUX DO - 最新话题
A
About on SuperTechFans
Google Online Security Blog
Google Online Security Blog
C
Cisco Blogs
Recent Announcements
Recent Announcements
Hacker News: Ask HN
Hacker News: Ask HN
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Vercel News
Vercel News
雷峰网
雷峰网
美团技术团队
D
DataBreaches.Net
Martin Fowler
Martin Fowler
Help Net Security
Help Net Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
F
Full Disclosure
博客园_首页

博客园 - 一名程序媛呀

Anki插件开发必知必会:钩子函数与右键菜单定制 httpx 传参总报错?这次把 GET、POST、文件上传到响应处理的坑给你一次填平 从卡顿到丝滑:FastAPI 调用外部 API 的正确姿势(httpx 实战) 还在 XHR、Fetch 和 Axios 之间纠结?我踩过的坑,希望你一个都不用碰到 你的REST接口还在“过度投喂”数据吗?——FastAPI + GraphQL实战避坑指南 Uvicorn、Gunicorn 傻傻分不清?FastAPI 生产部署避坑指南 Termux里的二进制和脚本,到底怎么运行才不踩坑?Termux-service 保活妙招! 刚部署的 LibreTranslate 频频翻车?我掏出了 20 年前的 StarDict 词典,用 FastAPI 搭了个本地词典翻译 API 别再用网页翻译看源码了!你的私人翻译神器LibreTranslate,部署避坑指南来了 掏出手机就能搭个 WebDAV 同步服务器?这操作有点香 别只盯着GitBook了!这个文档神器让你的笔记秒变网站 写爬虫时用了代理还被封?Python 代理的那些隐藏坑,我替你踩明白了 FastAPI 身份验证总踩坑?这份 FastAPI Users “避坑指南”请收好 旧手机别扔!用 Termux 搭个私人云盘,比网盘香多了 你的FastAPI又在服务器上“跑不起来”了?来,今天咱把打包这件事彻底聊透 写页面时别再把 Element Plus 整个搬进来啦!Vue3按需加载的坑我帮你踩平了 前端包管理咋选?我从npm叛逃到pnpm的血泪史(附避坑指南) 聊聊 fetch 使用中我踩过的那些坑和正确打开方式 FastApiAdmin 后端接口开发好了,前端管理界面怎么调用与显示? 给 FastApiAdmin 加个“会议纪要”模块,我把后端二次开发的坑踩了个遍 我用了FastApiAdmin后,连夜把踩过的坑都整理出来了 告别 Typora 后的新欢:我把所有笔记迁移到了 Obsidian 这个“第二大脑” 你的Agent API还在裸奔?从认证到沙箱,我用FastAPI搭了几道防线 让 FastAPI Agent 思考不阻塞:手把手教你实现异步任务与后台处理方案 让FastAPI Agent真正记住你:聊聊会话记忆与持久化存储的落地实践 FastAPI Agent 函数调用实战:我让 AI 学会了“自己动手查天气“ 初探:用 FastAPI 搭建你的第一个 AI Agent 接口 FastAPI 少有人提的实用技巧:把 Depends 依赖提到路由层,代码少写60% FastAPI 生产环境静态文件完全指南:从 /favicon.ico 404 到 HSTS 混合内容,一次全根治 用了loguru我才明白,Python日志还能这么写 FastAPI 后台任务:BackgroundTasks 的使用场景与注意事项 FastAPI配置管理避坑指南:从硬编码到 .env 与 pydantic_settings 类,连路由用法都给你捋清楚 FastAPI 文件上传避坑全指南:分块存盘、类型校验与安全兜底 FastAPI + Pydantic 模型终极实战手册:从能跑就行到固若金汤,这些技巧你一定用得上 FastAPI + SQLAlchemy 2.0 通用CRUD操作手册 —— 从同步到异步,一次讲透 FastAPI订单防超卖实战:从数据库锁到Saga分布式事务,这一篇给你理清了 FastAPI 生产环境避坑指南:用 Alembic 管理数据库迁移,别再手动改表结构了! FastAPI服务半夜又挂了?先别急着重启,查查你的数据库连接池“池子”是不是漏了 Vue 3 组件通信,别只会用 Props 和 Emits 了,这几个狠活儿你得看看 Vue 3 组合式 API 香是香,但从Vue2迁移时你可别像我当初一样踩进这 3 个深坑里 我用fastapi-scaff搭了个项目,两天工期缩到两小时,老板以为我开挂了 FastAPI+Vue:文件分片上传+秒传+断点续传,这坑我帮你踩平了! FastAPI自动生成的API文档太丑?我花了一晚上把它改成了客户愿意付费的样子 告别手写 API 胶水代码:FastAPI 与 Vue 的“契约自动机” OpenAPI 实战 FastAPI + Vue 前后端分离实战:我的项目结构“避坑指南” FastAPI + Celery 实战:异步任务里调用 Redis 和数据库的全解析,及生产级组织方案 FastAPI里玩转Redis和数据库的正确姿势,别让异步任务把你坑哭了! FastAPI + Celery 实战:异步任务的坑与解法,我帮你踩了一遍 FastAPI子应用挂载:别再让root_path坑你一夜 FastAPI项目半夜报警吵醒你?聊聊告警这事儿怎么搞! 别再数据线了!用FastAPI 5分钟搭个局域网文件+剪贴板神器 FastAPI单元测试实战:别等上线被喷才后悔,TestClient用对了真香! FastAPI状态共享秘籍:别再让中间件、依赖和路由“各自为政”了! FastAPI实战:WebSocket vs Socket.IO,这回真给我整明白了! 从0到1,FastAPI + PostgreSQL + Tortoise ORM 实战避坑指南 FastAPI + PostgreSQL 实战:给应用装上“缓存”和“日志”翅膀 FastAPI + PostgreSQL 实战:从入门到不踩坑,一次讲透
FastAPI数据库ORM怎么选?我肝了三个Demo后,终于不再纠结了
一名程序媛呀 · 2026-04-17 · via 博客园 - 一名程序媛呀

是不是每次开新项目,到了选ORM这一步,心里的两个小人就开始打架? 一个说:“用 SQLAlchemy 吧,生态稳如老狗,万一出问题网上随便一搜就有答案。” 另一个立马反驳:“异步时代了老铁,用 Tortoise-ORM 它不香吗?那代码写起来多轻快。” 旁边还有个声音幽幽飘来:“要不试试官方亲儿子 SQLModel ?”

别笑,这就是我之前的真实写照。我在 GitHub 上光是看这三个库的对比 issue 就刷了一下午,咖啡喝了三杯,一行代码没写。 最后索性一不做二不休,把这三个家伙挨个拉出来遛遛,写了个简单的用户CRUD,这才算心里有了谱。今天就把这份热乎的经验总结分享给你,主打一个听人劝吃饱饭。


🎯 这三兄弟到底谁是谁?

好,咱们先来盘盘这三位的底细。别嫌啰嗦,搞清楚它们的定位,你心里的秤杆子才能放平。

- SQLAlchemy 2.0:稳重的老大哥

这家伙在 Python 圈子的地位,好比 NBA 里的詹姆斯,资历老、技术全面、粉丝基础庞大。
以前总被人吐槽异步不行,但现在 2.0 版本原生支持 async/await,直接把最后一块短板也给补上了。

缺点就是学习曲线陡了点,配置起来稍微有点啰嗦。

- Tortoise-ORM:轻巧的赛车手

它就是为异步而生的,灵感来自 Django ORM。如果你从 Django 转过来,看这代码简直亲切得想哭。

它跑得快,占用资源少,但生态和社区肯定没老大哥那么广,有时候遇到冷门坑得自己去翻源码。

- SQLModel:官方的亲儿子

它是 FastAPI 作者 tiangolo 搞出来的,最大的杀招就是把 Pydantic 的 Schema 和 SQLAlchemy 的 Model 合二为一了。你再也不用写两份几乎一模一样的类了! 这简直是治愈强迫症的良药。

但它比较新,底层其实跑的还是 SQLAlchemy,可以理解为给老大哥穿了一身更潮的衣服。


🛠️ 别光说不练,上代码看看谁更顺手

咱们看个最简单的“创建用户”功能,直观感受下代码量的差距和手感。

1. SQLAlchemy 2.0 (异步版)

# 定义模型 (models.py)
class User(Base):
    __tablename__ = "users"
    id: Mapped[int] = mapped_column(primary_key=True)
    email: Mapped[str] = mapped_column(String(100), unique=True)

# Pydantic 校验 (schemas.py)
class UserCreate(BaseModel):
    email: str

# 路由逻辑 (main.py)
async def create_user(user_data: UserCreate, session: AsyncSession):
    new_user = User(**user_data.model_dump())
    session.add(new_user)
    await session.commit()
    await session.refresh(new_user)
    return new_user

⚠️ 经验之谈:看到没,模型和校验类是分开的。这里千万别学我当初偷懒,直接用同一个类又当校验又当数据库模型, 后面业务一复杂,比如数据库里要存个不对外暴露的字段,那改起来就是牵一发动全身。

2. Tortoise-ORM

# 定义模型 (models.py) 
class User(Model):
    id = fields.IntField(pk=True)
    email = fields.CharField(max_length=100, unique=True)

    class Meta:
        table = "users"

# 定义 Pydantic Schema (schemas.py)
class UserCreate(BaseModel):
    email: str

# 路由逻辑 (main.py)
async def create_user(user_data: UserCreate):
    new_user = await User.create(**user_data.model_dump())
    return new_user

是不是清爽多了?直接 User.create() 一把梭。但这也是它容易翻车的地方,因为太像 Django 了,有些人会忘记它底层的异步特性, 在循环里直接 await 搞出一堆慢查询。

3. SQLModel

# 定义模型 + Schema 合体 (models.py)
class User(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    email: str = Field(max_length=100, unique=True)

# 路由逻辑 (main.py)
async def create_user(user_data: User, session: AsyncSession):
    session.add(user_data)
    await session.commit()
    await session.refresh(user_data)
    return user_data

你可能会问:“这不就写了一个类吗?那登录时的密码字段怎么处理?” 问得好!SQLModel 的做法是用继承,再写个 UserCreate(User) 把敏感字段过滤掉。虽然文件少了,但对继承逻辑的理解要求高了点,刚上手容易蒙圈。


🤔 最后啰嗦一句,到底怎么选?

其实这个问题的答案,就像买螺丝刀,没有最贵的,只有最合适的。

🔹 如果你是团队开发大型项目:

别犹豫,直接上 SQLAlchemy 2.0。 生态和稳定性压倒一切,你踩过的坑前人早就把路填平了。虽然代码多点,但可控性强。

🔹 如果你是自己搞个小玩具,或者想快速出活:

Tortoise-ORM 会让你爽到飞起。 代码少,逻辑直观,异步性能杠杠的。

🔹 如果你是个强迫症,或者重度 Pydantic 爱好者:

试试 SQLModel 吧,官方亲儿子的名头不是白给的。 统一模型的感觉真的非常治愈。不过要做好当小白鼠的心理准备,毕竟它现在还是 0.x 版本。

说来说去,工具只是手段,能帮你解决问题的就是好工具。这篇文章也只是我个人的一点主观感受,真正哪个适合你,还得自己动手试试才知道。


好啦,今天先唠这么多。如果你觉得这篇用实战肝出来的对比有点用,别藏私,点个赞+关注,或者直接转发给你那个正在纠结 FastAPI 怎么写的同事。

技术路漫漫,咱们搭伴走不孤单。下次再遇到什么奇葩 Bug,咱们接着聊!👋