应用 SQLAlchemy 操作单表:以 SQLite 用户表为例的完整实战指南

news/2025/12/8 21:59:22/文章来源:https://www.cnblogs.com/tlnshuju/p/19323790

应用 SQLAlchemy 操作单表:以 SQLite 用户表为例的完整实战指南

2025-12-08 21:52  tlnshuju  阅读(0)  评论(0)    收藏  举报

作者:张大鹏
日期:2025年11月


一、前言

在 Python 的数据开发与后端工程中,SQLAlchemy 是最流行、最强大的 ORM 框架之一。
它不仅可以让我们像操作对象一样操作数据库,还能同时支持 ORM原生 SQL 两种方式。

本文将通过一个完整的示例,使用 SQLite 数据库和一张简单的 用户表(User)
详细介绍 SQLAlchemy 的单表操作:包括新增、查询、更新、删除、过滤、排序、分页等核心技术。


二、环境准备

1️⃣ 安装依赖

pip install sqlalchemy

✅ SQLite 为 Python 内置数据库,无需额外安装驱动。

2️⃣ 目录结构

project/
├── main.py
└── users.db

我们将在 main.py 中编写全部逻辑。


三、创建数据库连接与模型

1️⃣ 导入依赖并创建引擎

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import declarative_base, sessionmaker
# 创建数据库连接(SQLite)
DATABASE_URL = "sqlite:///users.db"
engine = create_engine(DATABASE_URL, echo=True)
# 创建基础类
Base = declarative_base()
# 创建会话工厂
SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False)

2️⃣ 定义用户模型

class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(50), nullable=False, unique=True)
email = Column(String(100), nullable=False, unique=True)
age = Column(Integer, default=18)
def __repr__(self):
return f"<User(id={self.id}, username='{self.username}', email='{self.email}', age={self.age})>"

3️⃣ 创建表结构

Base.metadata.create_all(engine)

执行后,将自动在本地生成 users.db 文件,并创建一张 users 表。


四、新增数据(Create)

方式一:单条插入

session = SessionLocal()
user = User(username="alice", email="alice@example.com", age=25)
session.add(user)
session.commit()
print("✅ 插入成功:", user)

方式二:批量插入

users = [
User(username="bob", email="bob@example.com", age=30),
User(username="charlie", email="charlie@example.com", age=22),
User(username="david", email="david@example.com", age=28),
]
session.add_all(users)
session.commit()
print("✅ 批量插入完成")

session.add() 用于单条,session.add_all() 可添加多条。
插入后必须 commit() 才会生效。


五、查询数据(Read)

SQLAlchemy 的查询非常灵活。
查询语法基于 session.query(),也可以使用新式 select() 语法(SQLAlchemy 2.x)。

1️⃣ 查询所有用户

users = session.query(User).all()
for u in users:
print(u)

2️⃣ 按条件过滤

# 查询单个用户
user = session.query(User).filter(User.username == "alice").first()
print(user)
# 查询年龄大于25的用户
users = session.query(User).filter(User.age > 25).all()
print(users)

3️⃣ 模糊匹配与逻辑条件

from sqlalchemy import or_, and_
# 模糊查询
users = session.query(User).filter(User.username.like("%a%")).all()
# 多条件查询
users = session.query(User).filter(
and_(User.age > 20, User.age < 30)
).all()
# 或条件
users = session.query(User).filter(
or_(User.username == "alice", User.username == "bob")
).all()

4️⃣ 排序与分页

# 按年龄降序
users = session.query(User).order_by(User.age.desc()).all()
# 分页:第2页,每页2条
page, page_size = 2, 2
users = session.query(User).offset((page - 1) * page_size).limit(page_size).all()

六、更新数据(Update)

更新操作可通过查询对象再修改属性完成。

1️⃣ 更新单条记录

user = session.query(User).filter(User.username == "alice").first()
if user:
user.age = 26
session.commit()
print("✅ 更新成功:", user)

2️⃣ 批量更新

session.query(User).filter(User.age < 25).update({"age": 25})
session.commit()
print("✅ 批量更新完成")

⚠️ 批量更新不会触发 ORM 对象的事件监听器,适用于直接数据库操作场景。


七、删除数据(Delete)

删除操作同样有两种方式。

1️⃣ 删除单条记录

user = session.query(User).filter(User.username == "bob").first()
if user:
session.delete(user)
session.commit()
print("✅ 已删除:", user)

2️⃣ 批量删除

session.query(User).filter(User.age < 25).delete()
session.commit()
print("✅ 批量删除完成")

八、原生 SQL 查询(可选)

虽然 ORM 更方便,但有时直接执行 SQL 也很有用。

from sqlalchemy import text
result = session.execute(text("SELECT * FROM users WHERE age >= :age"), {"age": 25})
for row in result.mappings():
print(row)

输出:

{'id': 1, 'username': 'alice', 'email': 'alice@example.com', 'age': 26}
{'id': 4, 'username': 'david', 'email': 'david@example.com', 'age': 28}

九、事务与异常处理

所有数据库操作都应放在事务中执行,并在异常时回滚。

try:
new_user = User(username="eve", email="eve@example.com", age=29)
session.add(new_user)
session.commit()
except Exception as e:
session.rollback()
print("❌ 发生错误,已回滚:", e)
finally:
session.close()

rollback() 可防止部分提交导致数据不一致。


十、总结与最佳实践

操作语法说明
新增session.add() / session.add_all()commit()
查询session.query(User)可配合 filter()order_by()
更新.update({...}) 或对象修改建议单条对象修改
删除.delete()session.delete()支持批量
原生 SQLsession.execute(text())灵活但需注意安全
事务控制try/except/rollback()避免脏数据

✅ 建议


十一、完整示例(可直接运行)

from sqlalchemy import create_engine, Column, Integer, String, text, and_
from sqlalchemy.orm import declarative_base, sessionmaker
# 数据库连接
engine = create_engine("sqlite:///users.db", echo=False)
Base = declarative_base()
SessionLocal = sessionmaker(bind=engine)
# 模型定义
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
username = Column(String(50), nullable=False, unique=True)
email = Column(String(100), nullable=False, unique=True)
age = Column(Integer)
Base.metadata.create_all(engine)
# 会话
session = SessionLocal()
# 增
session.add_all([
User(username="alice", email="alice@example.com", age=25),
User(username="bob", email="bob@example.com", age=30),
])
session.commit()
# 查
print(session.query(User).filter(User.age > 20).all())
# 改
session.query(User).filter(User.username == "alice").update({"age": 26})
session.commit()
# 删
session.query(User).filter(User.age < 25).delete()
session.commit()
session.close()

十二、延伸阅读


总结语

通过本文,你已经掌握了 SQLAlchemy 在单表操作中的核心能力:
增、删、改、查、过滤、排序、分页、事务与原生 SQL 执行

掌握这些知识后,你已经可以:

  • 构建一个完整的用户管理系统;
  • 进一步学习多表关系(ForeignKey, relationship);
  • 或者迁移到更强大的数据库(如 PostgreSQL、MySQL)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/993612.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

12-8午夜盘思

1、大盘无忧; 2、情绪方面:安记食品5连板,情绪周期强势延续;三市成交2万亿,抱团风格回归; 3、存储芯片:以存储芯片板块指数为锚点,板块上涨2.89%,板块强势;本质还是存储芯片涨价的故事;10cm方向,德明利领头…

MyBatis参数加解密

一、概述 在MyBatis中通过拦截器实现SQL参数加密/结果集解密是数据安全的常见场景,核心是拦截参数处理环节(加密入参)和结果集处理环节(解密出参)。适配Spring Boot3 + MyBatis环境。核心思路拦截点 作用 拦截接口…

基于Hadoop+数据可视化+机器学习随机森林预测算法+智能AI大模型+协同过滤推荐算法的青少年饮食习惯数据分析与可视化平台的设计与实现(精品源码+精品论文+上万材料集+答辩PPT)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

PyTorch推理扩展实战:用Ray Data轻松实现多机多卡并行

单机 PyTorch 模型跑推理没什么问题,但数据量一旦上到万级、百万级,瓶颈就暴露出来了:内存不够、GPU 利用率低、I/O 拖后腿,更别说还要考虑容错和多机扩展。 传统做法是自己写多线程 DataLoader、管理批次队列、手…

成膜助剂出口厂商有哪些?有出口资质的成膜助剂供应商名单推荐

成膜助剂作为涂料、胶粘剂等行业的核心功能性辅料,其供应稳定性、产品质量及出口服务能力直接影响下游产业发展。2025年,随着环保政策升级与国际贸易格局优化,具备出口资质、合规性强的成膜助剂厂商与贸易公司愈发受…

CF1994G

CF1994G因为异或每个位是独立的,只需要处理进位即可。 因此,考虑从低到高枚举每一位,记录进位个数,令 \(dp(i, j)\) 表示到第 \(i\) 位,进了 \(j\) 位的方案数。暴力枚举 \(0/1\) 转移即可。 时间复杂度:\(O(nk)…

2025婴儿车性价比排行榜首选:UPPAbaby MINU V3如何以轻便全能理念重新定义价值标准(附权威认证)

一、轻便婴儿车市场的价值认知革新 根据《2024中国母婴消费白皮书》(中国家庭教育学会发布)数据显示,在选购婴儿车时,87.3%的消费者将"轻便性"列为首要考量因素,但同时也有76.8%的用户担心轻便设计会牺…

陈阅视觉摄影培训机构发展历程

陈阅视觉摄影培训机构,成立于2009年,10多年来,陈阅视觉秉承“让摄影更加简单”的办学使命。 引进国外先进视觉传达课程体系,并结合国内特点,独立研发PLTA摄影教学系统,大力培养摄影与视频制作人才,有力推动国内…

hive ddl dml hivesql命令大全

SELECT T.sname,T.ctfid,T.gender,t.address,count(*) OVER(PARTITION BY T.sname) AS FM_CNTFROM test_db.room3 T WHERE T.address like "%北京%" AND instr(T.ctfid,310)>0 ORDER BY FM_CNT DESC;sel…

杭州刑事案件法律咨询找谁?刑事律师推荐

遇到刑事案件,时间就是生命。杭州刑事案件法律咨询找谁?今天给大家推荐一家专业的刑事辩护律所。 刑事案件为什么要尽早找律师? 黄金37天很关键,刑事拘留期:最长37天这个阶段律师能做什么:会见当事人了解案情;申…

【AI】第一篇:语言模型的前世 n-gram的简单介绍

1. N-gram 是什么?核心逻辑与“N”的含义 N-gram 是自然语言处理(NLP)中一种基于统计的语言模型,其核心思想是:一个词的出现概率,可以由它前面 N-1 个词来预测。它把文本按照连续的 N 个词(或字符)切分成片段(…

【12.11 直播】时序数据库 IoTDB FAQ 全面解答|下一期聊什么?你来决定!

集中解答你最想知道的问题,你还想了解什么?请告诉我们!🤔你在用时序数据库 IoTDB 时,是否也遇到过这些“灵魂拷问”: 🚀为什么我的查询无法执行? 💡树模型、表模型到底该如何选? 🔑如何与现有系统进行高…

12/8

今天满课,全是专业课,写了个Java系统,后端打不开,气死我了,晚上还要写统一建模语言

洛谷 P8189

洛谷 P8189有 \(n\) 个礼物分配给 \(n\) 个人,第 \(i\) 个人原本拥有第 \(i\) 个礼物,每个人都要一个喜欢程度的列表,现在他们可以交换礼物,但每个人最后得到的礼物的喜欢程度不能低于原本的礼物。 \(T\) 组询问,…

计算机毕业设计springboot图书销售框架设计与构建 基于 SpringBoot 的在线书城营销平台构建与实战 SpringBoot 驱动的数字化图书商城系统研发

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

12月8日

你永远无法想象未来会发生什么!

2025常州会计师事务所实力榜:汇丰所以审计创新与税务筹划优势领跑,江苏八城专业服务机构深度解析

2025常州会计师事务所实力榜:汇丰所以审计创新与税务筹划优势领跑,江苏八城专业服务机构深度解析 在长三角经济一体化与产业升级的宏观背景下,江苏省内企业的财务合规、战略咨询与风险管理需求日益精细化、专业化。…

题解:P14666 [KenOI 2025] 游走题

很好的数数题。 思路 观察样例,猜一个结论:游走的终点只可能是节点 \(1\)。考虑证明,一个节点如果往儿子走最终显然是可以再走回父亲的,但如果走到了父亲就不能再走回去了。所以只有走到一个没有父亲的点且把这个点…

你在用什么免费ip库?

事情是这样的,这几天我们站一直被不明ip频繁抓取数据! 6bdd3bee5195c13f7f6b00464f4fcda7 看了下都是越南的ip,你们遇到这种情况是怎么处理的? 导致我们的ip138经常使用过量。 老板让我找免费的ip库,找来找去找到了…

Python核心容器类型教程:列表、字典、元组、集合用法与实战

容器类型是Python处理数据的核心工具,掌握列表(List)、字典(Dict)、元组(Tuple)、集合(Set)这四类核心容器,能让你高效存储、遍历、操作数据——从简单的数据分析到复杂的业务逻辑开发,都离不开这些基础容器…