Python SQLAlchemy ORM 框架从入门到精通:核心概念与CRUD实战指南

发布时间:2026/9/22 20:15:39

Python SQLAlchemy ORM 框架从入门到精通:核心概念与CRUD实战指南 什么是SQLAlchemySQLAlchemy是Python中最流行的ORM对象关系映射框架它让开发者可以用Python对象操作数据库无需直接编写SQL语句。核心优势跨数据库兼容支持MySQL、PostgreSQL、SQLite等灵活的查询方式强大的事务支持完善的ORM映射机制SQLAlchemy核心概念SQLAlchemy分为两大模块Core核心组件和ORM对象关系映射。Core核心组件Engine引擎管理数据库连接Session会话数据库操作的桥梁Base基类所有ORM模型类的父类Model模型Python类对应数据库表Column字段定义表的字段和约束ORM对象关系映射ORM将Python对象与数据库表进行映射。核心优势无需编写原生SQL降低学习成本代码与数据库解耦便于维护和迁移自动处理数据类型转换支持事务管理和关联查询快速开始环境准备1. 安装SQLAlchemy及MySQL驱动pipinstallsqlalchemy pymysql2. 创建数据库CREATEDATABASEsqlalchemy_demo;创建Engine连接数据库fromsqlalchemyimportcreate_engine# 连接字符串格式数据库驱动://用户名:密码主机:端口/数据库名db_urlmysqlpymysql://root:123456localhost:3306/sqlalchemy_demoenginecreate_engine(db_url,echoTrue)# echoTrue打印SQL方便调试创建Base基类和Model模型fromsqlalchemy.ext.declarativeimportdeclarative_basefromsqlalchemyimportColumn,Integer,String,DateTimefromdatetimeimportdatetime# 创建Base基类Basedeclarative_base()# 定义User模型类classUser(Base):__tablename__user# 表名idColumn(Integer,primary_keyTrue,autoincrementTrue)usernameColumn(String(50),nullableFalse,uniqueTrue)passwordColumn(String(100),nullableFalse)create_timeColumn(DateTime,defaultdatetime.now)def__repr__(self):returnfUser(id{self.id}, username{self.username})创建数据表# 根据模型类自动创建表Base.metadata.create_all(engine)print(数据库表创建成功)创建Session实现数据库操作fromsqlalchemy.ormimportsessionmaker# 创建Session工厂SessionFactorysessionmaker(bindengine)# 插入数据sessionSessionFactory()userUser(usernamezhangsan,password123456)session.add(user)session.commit()session.close()# 查询数据sessionSessionFactory()all_userssession.query(User).all()foruinall_users:print(u)session.close()WHERE username ! ‘zhangsan’user2 session.query(User).filter(User.username ! “zhangsan”).all()print(f’{user2}‘)# 3. 模糊查询like对应 MySQL 的 WHERE username LIKE ‘%a%’user3 session.query(User).filter(User.username.like(“%a%”)).all()print(f’{user3}‘)# 4. 范围查询in_对应 MySQL 的 WHERE id IN (1,2,3)user4 session.query(User).filter(User.id.in_([1, 2, 3])).all()print(f’{user4}‘)# 5. 大于、小于、大于等于、小于等于user5 session.query(User).filter(User.id 2).all() # 对应 WHERE id 2print(f’{user5})# 6. 多条件查询and_ / or_对应 MySQL 的 AND / ORfrom sqlalchemy import and_, or_# 对应 WHERE id 1 AND username LIKE w% user6 session.query(User).filter(and_(User.id 1, User.username.like(w%))).first() print(f{user6}) # 对应 WHERE usernamezhangsan AND password123456 user7 session.query(User).filter_by(usernamezhangsan, password123456).first() print(f{user7}) # 对应 WHERE id 1 OR username LIKE w% user8 session.query(User).filter(or_(User.id 1, User.username.like(w%))).all() print(f{user8})#### 排序、分页查询 python from sqlalchemy_config import SessionFactory from base_model import User #导入Model模型 with SessionFactory() as session: # 1. 排序order_by对应 MySQL 的 ORDER BY users_asc session.query(User).order_by(User.id).all() # 按 id 升序默认对应 ORDER BY id ASC users_desc session.query(User).order_by(User.id.desc()).all() # 按 id 降序对应 ORDER BY id DESC print(f{users_asc}) print(f{users_desc}) # 2. 分页limit offset对应 MySQL 的 LIMIT 和 OFFSET适合分页查询 page 2 # 第 2 页 page_size 2 # 每页 2 条数据 # 对应 SELECT * FROM user ORDER BY id LIMIT 2 OFFSET 2 users_page session.query(User).order_by(User.id).limit(page_size).offset((page - 1) * page_size).all() print(f{users_page}) # 3. 统计数量count对应 MySQL 的 COUNT(*) user_count session.query(User).filter(User.username.like(z%)).count() print(f{user_count})分组查询函数作用func.count(字段)统计数量func.sum(字段)求和func.avg(字段)平均值func.max(字段)最大值func.min(字段)最小值fromsqlalchemy_configimportsessionFactory,funcfromsqlalchemyimportselectfrombase_modelimportUser,Accountwith(sessionFactory()assession):# 1.简单分组查询# 因为聚合函数是数据库提供的函数 所以需要导入func# 默认query(Account)查询所有列 聚合查询只能查询分组列与聚合函数所以# 所以需要查询指定列group1session.query(Account.age,func.count(Account.id)).group_by(Account.age).all()print(group1)# 聚合比较特殊 不会返回对应的对象 所以默认以元组返回# 如果想以字典形式返回需要使用新版2.0 API然后使用.mappings()stmtselect(Account.age,func.count(Account.id).label(count)).group_by(Account.age)group2session.execute(stmt).mappings().all()print(group2)# 2.having分组筛选# 可以直接使用having()进行分组的筛选group3session.query(Account.age,func.count(Account.id)).group_by(Account.age).having(func.count(Account.id)1).all()print(group3)stmtselect(Account.age,func.count(Account.id).label(count)).group_by(Account.age).having(func.count(Account.id)1)group4session.execute(stmt).mappings().all()print(group4)Create新增数据新增数据的步骤创建模型实例 → 将实例添加到会话 → 提交会话commit新增后的数据会直接写入 MySQL 数据库。fromsqlalchemy_configimportSessionFactoryfrombase_modelimportUser#导入Model模型withSessionFactory()assession:# 创建User实例相当于创建一条数据user1User(usernamelisi2,password123456)user2User(usernamewangwu2,password654321)# 1. 将实例添加到Session相当于“暂存”数据未提交到数据库session.add(user1)session.add(user2)# 提交事务将暂存的数据提交到数据库此时才会真正插入数据session.commit()# 2. 批量添加可选session.add_all([user1,user2])session.commit()# 3. 批量字典添加# 准备字典列表不用创建User对象user_dicts[{username:sunqi,password:123123},{username:zhouba,password:456456},{username:wujiu,password:789789},]# 4. 批量插入session.bulk_insert_mappings(User,user_dicts)session.commit()# 5. sqlalchemy2.0语法fromsqlalchemyimportinsert# 构建insert语句stmtinsert(User).values([{username:zhengshi,password:aaa},{username:chenshi,password:bbb},])# 执行语句session.execute(stmt)session.commit()Delete删除数据删除数据的步骤查询数据 → 删除实例 → 提交会话删除操作会直接删除 MySQL 中的对应数据。fromsqlalchemy_configimportSessionFactoryfrombase_modelimportUser#导入Model模型fromsqlalchemyimportdeletewithSessionFactory()assession:# 1. 单条数据删除usersession.query(User).filter(User.usernamewangwu).first()ifuser:session.delete(user)# 对应 DELETE FROM user WHERE username wangwusession.commit()# 2. 批量删除对应 MySQL 的 DELETE ... WHERE ...# 删除所有 id 3 的用户session.query(User).filter(User.id3).delete()session.commit()# 3. sqlalchemy2.0语法fromsqlalchemyimportdelete# 构建 delete 语句stmtdelete(User).where(User.id18)# 执行语句session.execute(stmt)session.commit()Update更新数据更新数据的步骤查询数据 → 修改实例属性 → 提交会话更新操作会直接同步到 MySQL 数据库。fromsqlalchemy_configimportSessionFactoryfrombase_modelimportUser#导入Model模型withSessionFactory()assession:# 1. 单条数据更新usersession.query(User).filter(User.usernamezhangsan).first()ifuser:user.passwordnew_password123# 修改密码对应 UPDATE user SET password new_password123session.commit()# 提交更新print(f{user})# 2. 批量更新高效对应 MySQL 的 UPDATE ... WHERE ...# 将所有用户名以 w 开头的用户密码更新为 common_passwordsession.query(User).filter(User.username.like(w%)).update({password:common_password})session.commit()# 3. sqlalchemy2.0语法fromsqlalchemyimportupdate# 构建 update 语句stmtupdate(User).where(User.username.like(w%)).values(passwordsqlalchemy2.0_password)# 执行语句session.execute(stmt)session.commit()
延伸阅读

更多相关文章

2026/9/20 22:30:06

Samba安全加固:修改默认端口与Windows客户端连接配置详解

1. 项目概述:为什么需要更改Samba的默认端口?如果你在Linux服务器上部署了Samba服务,用它来和Windows电脑共享文件,那么“端口”这个词对你来说一定不陌生。默认情况下,Samba使用445和139这两个端口来和Windows系统通信…

2026/9/20 22:30:25

LeetCode 1888题解析:二进制字符串交替转换的最优解法

1. 问题背景与核心需求这道LeetCode 1888题"使二进制字符串字符交替的最少反转次数"考察的是对二进制字符串的操作技巧。题目要求我们通过两种操作类型,将任意给定的二进制字符串转换成字符交替的形式(即"0101..."或"1010...&q…

2026/9/20 22:30:25

5V转1.2V电源设计:LDO与开关降压方案深度对比与实战选型

1. 从5V到1.2V:一个看似简单却暗藏玄机的电源设计 在嵌入式系统、FPGA核心供电或者低功耗MCU的设计中,我们常常会遇到一个非常经典的电源转换需求:将常见的5V系统总线电压,稳定、高效地降压到1.2V,为那些对电压精度和噪…

2026/9/22 20:11:28

3天搞定章纪民高频面试题,前端视角拆解施工企业痛点

3天搞定章纪民高频面试题,前端视角拆解施工企业痛点 面试被问原理答不上来,那种脑子一片空白的感觉,真的比代码报错还难受。特别是当面试官盯着你的眼睛,问起“章纪民”相关的前端实现逻辑,或者如何结合施工现场的违规数据做可视化展示时,你如果只能支…

2026/9/22 20:11:28

3步搞定中兴u880刷机包解析,面试必问细节全公开

3步搞定中兴u880刷机包解析,面试必问细节全公开 复制来的刷机脚本一跑就报错?参数对不上、分区表解析失败,这种“代码看着都对但就是跑不通”的崩溃感,我懂。很多学员在刷中兴u880这类老旧机型时,卡在数据校验这一步,不知道是包的问题还是代码…

2026/9/22 20:11:28

2026最新养肝护肝的中药技术选型避坑指南

2026最新养肝护肝的中药技术选型避坑指南 面试被问“为什么选这个库”答不上来?2026最新的技术栈迭代太快,很多人还在用三年前的经验硬扛,结果在白板前卡壳。别慌,今天咱们不聊虚的,直接拆解【养肝护肝的中药】这个隐喻背后的技术本质——即如何…

2026/9/22 20:11:28

物联网电池新手避坑:3个核心优化让设备续航翻倍

物联网电池新手避坑:3个核心优化让设备续航翻倍 报错堆满屏幕,StackTrace 一片红,看着像天书。刚接手物联网电池监控项目的新手,最头疼的不是逻辑,而是性能。设备在线率忽高忽低,电池电量估算飘忽不定,日志里全是 Timeout 和…

2026/9/22 10:02:42

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/22 9:07:39

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/22 0:04:49

输电线路在线监测高频面试题拆解 3秒抓住官方文档重点

输电线路在线监测高频面试题拆解 3秒抓住官方文档重点 官方文档几百页翻到头还是懵?面试问到 输电线路在线监测 的数据链路时,脑子一片空白?别慌,这种 高频面试题 我整理了10年,专门治各种“文档太长抓不住重点”的毛病。…

2026/9/22 0:04:49

中介房源管理系统重构避坑:3个关键步骤搞定API变更

中介房源管理系统重构避坑:3个关键步骤搞定API变更 版本升级后 API 全变了,这种痛只有真做过的人懂。 很多团队在接手老旧房产项目时,最崩溃的不是代码烂,而是底层框架升级后,原本熟悉的接口调用方式彻底失效。 这份 保姆级教程…

2026/9/22 0:04:49

3个坑点带你一文搞懂55gg小游戏源码

3个坑点带你一文搞懂55gg小游戏源码 盯着控制台满屏的红色报错,看着那一长串 StackTrace ,是不是脑子瞬间宕机?别急,这种时候最忌讳的就是盲目改代码。很多刚入行的前端同学,面对 55gg 小游戏这类轻量级 H5…

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/22 20:01:30

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码