Python SQLAlchemy 与数据库操作讲解

发布时间:2026/8/27 9:47:42

Python SQLAlchemy 与数据库操作讲解
文章目录一、核心概念二、安装三、快速开始SQLAlchemy 2.0 风格1. 创建引擎与基类2. 定义模型3. 创建表四、最常用的 CRUD 操作1. 增加Create2. 查询Read3. 更新Update4. 删除Delete五、关系查询六、FastAPI 中的典型用法七、事务与异常处理八、Alembic 数据库迁移强烈建议九、最佳实践十、Core 与 ORM 如何选择SQLAlchemy 是 Python 中最强大、最流行的 SQL 工具包同时支持ORM对象关系映射和Core核心表达式两种风格。现代项目推荐使用SQLAlchemy 2.0风格API 更清晰、类型提示更好。一、核心概念概念说明Engine数据库连接池的入口负责管理连接SessionORM 的工作单元负责对象的增删改查Model普通 Python 类对应数据库表Core更接近 SQL 的表达式语言性能更高、更灵活ORM用对象操作数据库开发效率高大多数 Web 项目尤其 FastAPI使用 ORM 风格即可。二、安装pipinstallsqlalchemy# 根据数据库选择驱动pipinstallpsycopg2-binary# PostgreSQLpipinstallpymysql# MySQLpipinstallaiosqlite# SQLite 异步可选三、快速开始SQLAlchemy 2.0 风格1. 创建引擎与基类fromsqlalchemyimportcreate_enginefromsqlalchemy.ormimportDeclarativeBase,sessionmaker,Mapped,mapped_column# 数据库连接地址DATABASE_URLsqlite:///./test.db# PostgreSQL 示例postgresql://user:passwordlocalhost/dbnameenginecreate_engine(DATABASE_URL,echoTrue,# 打印实际执行的 SQL开发时建议开启)classBase(DeclarativeBase):pass# 创建 Session 工厂SessionLocalsessionmaker(bindengine,autoflushFalse,autocommitFalse)2. 定义模型fromdatetimeimportdatetimefromsqlalchemyimportString,Integer,DateTime,ForeignKey,Textfromsqlalchemy.ormimportMapped,mapped_column,relationshipclassUser(Base):__tablename__usersid:Mapped[int]mapped_column(primary_keyTrue)name:Mapped[str]mapped_column(String(50),indexTrue)email:Mapped[str]mapped_column(String(100),uniqueTrue,indexTrue)age:Mapped[int|None]mapped_column(Integer,nullableTrue)created_at:Mapped[datetime]mapped_column(DateTime,defaultdatetime.now)# 一对多关系posts:Mapped[list[Post]]relationship(back_populatesauthor)classPost(Base):__tablename__postsid:Mapped[int]mapped_column(primary_keyTrue)title:Mapped[str]mapped_column(String(200))content:Mapped[str]mapped_column(Text)user_id:Mapped[int]mapped_column(ForeignKey(users.id))author:Mapped[User]relationship(back_populatesposts)3. 创建表Base.metadata.create_all(bindengine)四、最常用的 CRUD 操作fromsqlalchemyimportselect# 获取 Sessiondefget_db():dbSessionLocal()try:yielddbfinally:db.close()1. 增加CreatedbSessionLocal()userUser(nameAlice,emailaliceexample.com,age25)db.add(user)db.commit()# 提交事务db.refresh(user)# 刷新对象获取数据库生成的 id 等print(user.id)# 批量添加db.add_all([User(nameBob,emailbobexample.com),User(nameCharlie,emailcharlieexample.com),])db.commit()2. 查询Read# 查询所有usersdb.scalars(select(User)).all()# 按主键查询userdb.get(User,1)# 条件查询stmtselect(User).where(User.age20).order_by(User.id.desc())usersdb.scalars(stmt).all()# 查询第一条userdb.scalars(select(User).where(User.emailaliceexample.com)).first()# 只获取部分字段stmtselect(User.name,User.email)resultsdb.execute(stmt).all()3. 更新Updateuserdb.get(User,1)ifuser:user.age26user.nameAlice Updateddb.commit()或者使用update语句适合批量fromsqlalchemyimportupdate stmtupdate(User).where(User.id1).values(age26)db.execute(stmt)db.commit()4. 删除Deleteuserdb.get(User,1)ifuser:db.delete(user)db.commit()五、关系查询# 创建用户和文章userUser(nameAlice,emailaliceexample.com)post1Post(title第一篇文章,content内容...,authoruser)post2Post(title第二篇文章,content内容...,authoruser)db.add(user)# 级联添加 posts需要配置 cascadedb.commit()# 查询用户时加载文章userdb.scalars(select(User).where(User.id1)).first()print(user.posts)# 自动加载相关文章默认 lazy常用关系加载策略lazyselect默认lazyjoined连表一次加载lazyselectin推荐适合一对多六、FastAPI 中的典型用法fromfastapiimportDepends,FastAPI,HTTPExceptionfromsqlalchemy.ormimportSession appFastAPI()defget_db():dbSessionLocal()try:yielddbfinally:db.close()app.post(/users/)defcreate_user(name:str,email:str,db:SessionDepends(get_db)):userUser(namename,emailemail)db.add(user)db.commit()db.refresh(user)returnuserapp.get(/users/{user_id})defread_user(user_id:int,db:SessionDepends(get_db)):userdb.get(User,user_id)ifnotuser:raiseHTTPException(status_code404,detail用户不存在)returnuser七、事务与异常处理dbSessionLocal()try:userUser(nameAlice,emailaliceexample.com)db.add(user)db.commit()exceptException:db.rollback()# 出错回滚raisefinally:db.close()在 FastAPI 的依赖中通常把commit放在业务逻辑成功后异常时自动回滚。八、Alembic 数据库迁移强烈建议直接create_all只适合开发阶段。生产环境应使用Alembic做版本化迁移。pipinstallalembic alembic init alembic常用命令alembic revision--autogenerate-mcreate users tablealembic upgradeheadalembic downgrade-1九、最佳实践使用 SQLAlchemy 2.0 风格Mapped、mapped_column、select()Session 生命周期要短不要长期持有生产环境关闭echoTrue合理使用索引indexTrue、uniqueTrue关系加载注意 N1 问题必要时用selectinload或joinedload密码等敏感字段不要明文存储大型项目推荐把 Model、Session、CRUD 分层优先使用 Alembic 管理表结构变更十、Core 与 ORM 如何选择ORM开发速度快适合大多数业务系统Core需要极致性能、复杂 SQL、批量操作时更合适两者可以在同一项目中混合使用。 感谢阅读想了解更多 我的博客网站 | 记录思考分享干货 我的个人主页 | 关于我、开源项目

相关新闻

Java大厂面试实录:Spring Boot + Kafka + Redis + Spring Security + RAG 的三轮攻防

Java大厂面试实录:Spring Boot + Kafka + Redis + Spring Security + RAG 的三轮攻防

2026/8/27 9:47:41

Java大厂面试实录:Spring Boot Kafka Redis Spring Security RAG 的三轮攻防场景:某互联网大厂 Java 岗位面试现场。面试官表情严肃,候选人燕双非一脸轻松,主打一个“我可能不全会,但我会努力胡说八道”。第一轮&a…

跨境ETF套利策略设计:从理论价差到实战风控

跨境ETF套利策略设计:从理论价差到实战风控

2026/8/27 9:37:41

1. 从一道赛题到实战:跨境ETF套利策略的深度拆解 最近翻看去年的一些数学建模竞赛题目,发现“2023大湾区杯”的A题“跨境ETF套利策略设计”很有意思。这道题没有像很多传统题目那样给出海量的历史数据让你去拟合,而是直接抛出了一个非常贴近真…

MCU供电设计:新一代LDO选型与板级布局实践

MCU供电设计:新一代LDO选型与板级布局实践

2026/8/27 9:37:41

一块以MCU为核心的控制板,ADC采样值莫名跳动,从十几LSB慢慢涨到几十LSB,程序里加了多少次均值滤波都压不住。当时我下意识怀疑是参考电压的问题,查了基准源、查了参考走线,折腾两天没结果。最后把示波器探头直接点在LD…

自媒体传播建模实战:SEIR改进与元胞自动机嵌套设计

自媒体传播建模实战:SEIR改进与元胞自动机嵌套设计

2026/8/27 10:47:54

1. 这不是一份“标准答案”,而是一份真实跑通的建模手记2017年五一杯数学建模B题——“自媒体时代的消息传播问题”,表面看是道典型的传染病模型题,但真正动手做下来,你会发现它根本不是套个SEIR公式、调个ode45就能交卷的作业。我…

产品动态设计实战:从SURI牙刷看品牌视觉叙事与工作流

产品动态设计实战:从SURI牙刷看品牌视觉叙事与工作流

2026/8/27 10:47:54

一个动态设计作品被放到评审会上,客户看完后提出的第一个问题往往不是“这个镜头语言是否准确”,而是“牙刷能不能转得再快一点”。真正做过产品动态设计的人都知道,这种反馈背后的问题从来不是转速,而是整支片子没有建立起一个让…

随手记录 利用全志T153,点亮OLED屏幕,显示当地天气

随手记录 利用全志T153,点亮OLED屏幕,显示当地天气

2026/8/27 10:47:54

学习了正点原子的imx6ull 好几遍,有了思路框架后,想试试自己不靠教程点亮个屏幕试试,手上有两块创龙的开发板,先玩玩T153吧。我用的是docker 容器当开发环境,在Windows上远程开发。(需要先执行提供的脚本&a…

LoRA权重合并实战:从分体式微调到一体化模型部署

LoRA权重合并实战:从分体式微调到一体化模型部署

2026/8/27 10:47:54

1. 从“分体式”到“一体化”:为什么我们需要合并LoRA权重 如果你最近在折腾大语言模型微调,尤其是用上了像LLaMA-7B、Qwen这样的开源基座,那你大概率已经接触过LoRA(Low-Rank Adaptation)这种高效的微调方法了。它的好…

CPLD与FPGA有什么区别

CPLD与FPGA有什么区别

2026/8/27 10:47:54

CPLD和FPGA都是可编程逻辑器件,核心区别可以这样理解:CPLD更像是一块在出厂时(或通过简单编程)就固定了“硬逻辑”的电路板,上电即用,时序精确;而FPGA则像一堆可以任意组合的“乐高积木”,功能更强大、更灵活,但需要在上电时从外部加载配置 ⚙️ 核心架构与逻辑实现 …

AI编码代理的隐性成本:“氛围税”如何悄悄拖慢你的团队

AI编码代理的隐性成本:“氛围税”如何悄悄拖慢你的团队

2026/8/27 10:37:44

我们团队引入 AI 编码代理已经半年了,最开始的体感是真的爽。新功能从需求到原型,代码补全几乎不用等,甚至能一口气生成一整套文件。但最近一次复盘,大家算了一笔账之后沉默了:效率提升没有想象中明显,反而…

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

2026/8/26 1:50:39

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

2026/8/27 7:25:23

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

2026/8/26 17:50:58

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

Go语言构建企业级AI服务网关:统一管理英伟达等AI接口调用

Go语言构建企业级AI服务网关:统一管理英伟达等AI接口调用

2026/8/27 0:07:12

1. 项目概述:从零构建一个企业级的AI服务网关 最近在帮一个做内容审核的团队做技术架构升级,他们原来的业务里,每天有几十万张图片和短视频需要过审,最初是接了几个开源的AI模型自己部署,但效果和性能一直不太稳定。后…

LeetCode Hot100(51-60)算法精解与面试技巧

LeetCode Hot100(51-60)算法精解与面试技巧

2026/8/27 0:07:12

1. 题目背景与核心价值"hot100(51-60)"这个标题看起来像是某个编程题库或算法练习集中的一组题目编号。在技术社区中,类似命名通常指向LeetCode、牛客网等平台的热门题目集合。作为刷过300题的算法老手,我理解这类题目的核心价值在于&#xff…

CRC校验实战:从模2除法到HJ212协议排错

CRC校验实战:从模2除法到HJ212协议排错

2026/8/27 0:07:12

1. 为什么一个“校验码”能扛住工业现场90%的数据 corruption? 你有没有遇到过这样的场景:嵌入式设备通过RS-485上传温湿度数据,上位机偶尔收到一帧乱码——温度显示成-273℃,湿度跳到999%,但串口波形看起来完全正常&a…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/22 2:02:26

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/26 18:07:30

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/26 17:57:52

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…