Python单元测试(unittest)实战指南
SQLAlchemy是Python中最流行的ORM对象关系映射框架之一它提供了高效且灵活的数据库操作方式。本文将介绍如何使用SQLAlchemy ORM进行数据库操作。目录安装SQLAlchemy核心概念连接数据库定义数据模型创建数据库表基本CRUD操作查询数据关系操作事务管理最佳实践安装bashpip install sqlalchemy如果需要连接特定数据库还需安装相应的驱动程序bash# PostgreSQL pip install psycopg2-binary # MySQL pip install mysql-connector-python # SQLite (Python标准库已包含无需额外安装)核心概念Engine数据库连接的引擎负责与数据库通信Session数据库会话管理所有持久化操作Model数据模型类对应数据库中的表Query查询对象用于构建和执行数据库查询连接数据库pythonfrom sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker # 创建数据库连接引擎 # SQLite示例 engine create_engine(sqlite:///example.db, echoTrue) # PostgreSQL示例 # engine create_engine(postgresql://username:passwordlocalhost:5432/mydatabase) # MySQL示例 # engine create_engine(mysqlmysqlconnector://username:passwordlocalhost:3306/mydatabase) # 创建会话工厂 SessionLocal sessionmaker(autocommitFalse, autoflushFalse, bindengine) # 创建会话实例 session SessionLocal()定义数据模型pythonfrom sqlalchemy import Column, Integer, String, ForeignKey from sqlalchemy.orm import relationship, declarative_base # 创建基类 Base declarative_base() class User(Base): __tablename__ users id Column(Integer, primary_keyTrue, indexTrue) name Column(String(50), nullableFalse) email Column(String(100), uniqueTrue, indexTrue) # 定义一对多关系 posts relationship(Post, back_populatesauthor) class Post(Base): __tablename__ posts id Column(Integer, primary_keyTrue, indexTrue) title Column(String(100), nullableFalse) content Column(String(500)) author_id Column(Integer, ForeignKey(users.id)) # 定义多对一关系 author relationship(User, back_populatesposts) # 定义多对多关系通过关联表 tags relationship(Tag, secondarypost_tags, back_populatesposts) class Tag(Base): __tablename__ tags id Column(Integer, primary_keyTrue, indexTrue) name Column(String(30), uniqueTrue, nullableFalse) posts relationship(Post, secondarypost_tags, back_populatestags) # 关联表用于多对多关系 class PostTag(Base): __tablename__ post_tags post_id Column(Integer, ForeignKey(posts.id), primary_keyTrue) tag_id Column(Integer, ForeignKey(tags.id), primary_keyTrue)创建数据库表python# 创建所有表 Base.metadata.create_all(bindengine) # 删除所有表 # Base.metadata.drop_all(bindengine)基本CRUD操作创建数据python# 创建新用户 new_user User(name张三, emailzhangsanexample.com) session.add(new_user) session.commit() # 批量创建 session.add_all([ User(name李四, emaillisiexample.com), User(name王五, emailwangwuexample.com) ]) session.commit()读取数据python# 获取所有用户 users session.query(User).all() # 获取第一个用户 first_user session.query(User).first() # 根据ID获取用户 user session.query(User).get(1)更新数据python# 查询并更新 user session.query(User).get(1) user.name 张三四 session.commit() # 批量更新 session.query(User).filter(User.name.like(张%)).update({name: 张氏}, synchronize_sessionFalse) session.commit()删除数据python# 查询并删除 user session.query(User).get(1) session.delete(user) session.commit() # 批量删除 session.query(User).filter(User.name 李四).delete(synchronize_sessionFalse) session.commit()查询数据基本查询python# 获取所有记录 users session.query(User).all() # 获取特定字段 names session.query(User.name).all() # 排序 users session.query(User).order_by(User.name.desc()).all() # 限制结果数量 users session.query(User).limit(10).all() # 偏移量 users session.query(User).offset(5).limit(10).all()过滤查询pythonfrom sqlalchemy import or_ # 等值过滤 user session.query(User).filter(User.name 张三).first() # 模糊查询 users session.query(User).filter(User.name.like(张%)).all() # IN查询 users session.query(User).filter(User.name.in_([张三, 李四])).all() # 多条件查询 users session.query(User).filter( User.name 张三, User.email.like(%example.com) ).all() # 或条件 users session.query(User).filter( or_(User.name 张三, User.name 李四) ).all() # 不等于 users session.query(User).filter(User.name ! 张三).all()聚合查询pythonfrom sqlalchemy import func # 计数 count session.query(User).count() # 分组计数 user_post_count session.query( User.name, func.count(Post.id) ).join(Post).group_by(User.name).all() # 求和、平均值等 avg_id session.query(func.avg(User.id)).scalar()连接查询python# 内连接 results session.query(User, Post).join(Post).filter(Post.title.like(%Python%)).all() # 左外连接 results session.query(User, Post).outerjoin(Post).all() # 指定连接条件 results session.query(User, Post).join(Post, User.id Post.author_id).all()关系操作python# 创建带关系的对象 user User(name赵六, emailzhaoliuexample.com) post Post(title我的第一篇博客, contentHello World!, authoruser) session.add(post) session.commit() # 通过关系访问 print(f文章 {post.title} 的作者是 {post.author.name}) print(f用户 {user.name} 的所有文章:) for p in user.posts: print(f - {p.title}) # 多对多关系操作 python_tag Tag(namePython) sqlalchemy_tag Tag(nameSQLAlchemy) post.tags.append(python_tag) post.tags.append(sqlalchemy_tag) session.commit() print(f文章 {post.title} 的标签:) for tag in post.tags: print(f - {tag.name})事务管理python# 自动提交事务 try: user User(name测试用户, emailtestexample.com) session.add(user) session.commit() except Exception as e: session.rollback() print(f发生错误: {e}) # 使用事务上下文管理器 from sqlalchemy.orm import Session def create_user(session: Session, name: str, email: str): try: user User(namename, emailemail) session.add(user) session.commit() return user except: session.rollback() raise # 嵌套事务 with session.begin_nested(): user User(name事务用户, emailtransactionexample.com) session.add(user) # 保存点 savepoint session.begin_nested() try: user User(name保存点用户, emailsavepointexample.com) session.add(user) savepoint.commit() except: savepoint.rollback()最佳实践会话管理为每个请求创建新会话请求结束后关闭异常处理始终处理异常并适当回滚事务延迟加载注意N1查询问题使用 eager loading 优化连接池合理配置连接池大小和超时设置数据验证在模型层或应用层验证数据完整性python# 使用上下文管理器管理会话 from contextlib import contextmanager contextmanager def get_db(): db SessionLocal() try: yield db db.commit() except Exception: db.rollback() raise finally: db.close() # 使用示例 with get_db() as db: user User(name上下文用户, emailcontextexample.com) db.add(user)总结SQLAlchemy ORM提供了强大而灵活的数据库操作方式通过本文的介绍您应该能够安装和配置SQLAlchemy定义数据模型和关系执行基本的CRUD操作构建复杂查询管理数据库事务遵循最佳实践SQLAlchemy还有更多高级特性如混合属性、事件监听、自定义查询等值得进一步探索学习。

相关新闻

移动设备上的C++优化

移动设备上的C++优化

1、非修改序列算法 这些算法不会改变它们所操作的容器中的元素。 1.1 find 和 find_if find(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。find_if(begin, end, predicate):查找第…

2026/7/3 15:02:29 阅读更多 →
基于单片机的无线病床呼叫系统设计

基于单片机的无线病床呼叫系统设计

文章目录 摘要一、系统功能二、总体设计三、效果图源码获取 摘要 本文设计并实现了一种基于单片机的无线病床呼叫系统,旨在提高医院的服务水平和管理效率,确保病人得到及时有效的医疗服务。系统以STC89C51单片机为核心控制器,结合无线通信技术…

2026/7/5 3:54:37 阅读更多 →
Java毕设项目:基于springboot的学车驾校管理系统(源码+文档,讲解、调试运行,定制等)

Java毕设项目:基于springboot的学车驾校管理系统(源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/3 4:59:56 阅读更多 →

最新新闻

11、<简单>有一个六位数,其个位数字7,现将个位数字移至首位(十万位),而其余各位数字顺序不变,均后退一位,得到一个新的六位数,假如新数为I旧数的4倍,求原来的六位数

11、<简单>有一个六位数,其个位数字7,现将个位数字移至首位(十万位),而其余各位数字顺序不变,均后退一位,得到一个新的六位数,假如新数为I旧数的4倍,求原来的六位数

#include <iostream> using namespace std;int main() {// old 是原六位数&#xff0c;个位固定为7for (long old 100007; old < 999997; old 10){// 拆分前5位long front old / 10;// 个位7移到十万位&#xff0c;生成新六位数long newNum 700000 front;// 判断…

2026/7/5 13:40:12 阅读更多 →
终极精简指南:使用PowerShell脚本让Windows 11瘦身50%

终极精简指南:使用PowerShell脚本让Windows 11瘦身50%

终极精简指南&#xff1a;使用PowerShell脚本让Windows 11瘦身50% 【免费下载链接】tiny11builder Scripts to build a trimmed-down Windows 11 image. 项目地址: https://gitcode.com/GitHub_Trending/ti/tiny11builder 你是否曾为Windows 11那臃肿的系统体积和缓慢的…

2026/7/5 13:40:12 阅读更多 →
从《中国统计年鉴》到可比数据:手把手教你计算不变价GDP

从《中国统计年鉴》到可比数据:手把手教你计算不变价GDP

1. 为什么需要计算不变价GDP&#xff1f; 我第一次接触GDP数据时&#xff0c;发现一个奇怪现象&#xff1a;某城市2000年GDP是1000亿元&#xff0c;2020年GDP是8000亿元&#xff0c;看起来增长了8倍。但老师告诉我&#xff0c;这个比较毫无意义&#xff0c;因为没考虑物价变化。…

2026/7/5 13:40:12 阅读更多 →
编程启蒙|Scratch 转 Python 系列第 3 天完整教程

编程启蒙|Scratch 转 Python 系列第 3 天完整教程

本篇是零基础 Python 自学系列 Scratch 转 Python 第 3 天笔记&#xff0c;适合纯小白入门&#xff0c;内容包含实操代码、详细讲解与配套练习题&#xff0c;全程 Scratch 积木代码 Python 双向对照教学。 一、昨日内容复盘&#xff08;Scratch 转 Python Day2 for 循环与 ra…

2026/7/5 13:36:11 阅读更多 →
玄鹿电竞:用技术重构游戏服务体验,驱动专业护航

玄鹿电竞:用技术重构游戏服务体验,驱动专业护航

在《三角洲行动》的战场中&#xff0c;你是否曾因“老六蹲撤”“摸金翻车”“任务卡关”而遗憾&#xff1f;玄鹿电竞以技术为引擎&#xff0c;打造全链路专业护航平台&#xff0c;从下单、匹配、服务到售后&#xff0c;用数字化架构重构游戏服务体验&#xff0c;让“稳撤满载”…

2026/7/5 13:34:10 阅读更多 →
18、<简单>寻找距离2的幂最近的数字

18、<简单>寻找距离2的幂最近的数字

#include <iostream> using namespace std;int main() {int n;cout << "请输入整数n&#xff1a;";cin >> n;// 先找到小于等于n的最大2的幂 lowint low 1;while (low * 2 < n){low * 2;}int high low * 2; // 大于n的最小2的幂int dis_low …

2026/7/5 13:32:10 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools&#xff1a;5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱&#xff0c;支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里&#xff0c;参与了关于混合后量子密码学的讨论&#xff0c;应付端点攻击找茬的人&#xff0c;还参与留言板讨论后&#xff0c;发现“威胁模型”对多数人仍是陌生概念&#xff0c;且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”&#xff1a;我理解的渗透测试到底是什么&#xff1f;每次看到新闻里说某个大公司的数据被“黑”了&#xff0c;或者某个网站被攻击导致服务瘫痪&#xff0c;你是不是和我一样&#xff0c;心里会冒出两个念头&#xff1a;一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools&#xff1a;5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱&#xff0c;支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里&#xff0c;参与了关于混合后量子密码学的讨论&#xff0c;应付端点攻击找茬的人&#xff0c;还参与留言板讨论后&#xff0c;发现“威胁模型”对多数人仍是陌生概念&#xff0c;且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”&#xff1a;我理解的渗透测试到底是什么&#xff1f;每次看到新闻里说某个大公司的数据被“黑”了&#xff0c;或者某个网站被攻击导致服务瘫痪&#xff0c;你是不是和我一样&#xff0c;心里会冒出两个念头&#xff1a;一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻