Python 课程18-SQLAlchemy
前言
SQLAlchemy 是一个功能强大的 Python SQL 工具包和对象关系映射(ORM)库,它使得开发者能够通过 Python 代码与数据库进行交互,而不必编写 SQL 查询。SQLAlchemy 提供了对多种数据库的支持,包括 MySQL、PostgreSQL、SQLite 等,适用于从简单的小项目到复杂的大型系统。
本教程将带你从 SQLAlchemy 的基础操作(如连接数据库、创建模型、执行查询等)到高级功能(如事务管理、关系映射等),并提供详细的代码示例。
目录
-
SQLAlchemy 基础
- 安装 SQLAlchemy
- 创建数据库连接
- 使用 SQLAlchemy Core 执行原生 SQL 查询
-
ORM 基础
- 定义模型(Classes as Tables)
- 创建表结构
- 插入、查询、更新、删除数据
-
关系映射
- 一对多关系
- 多对多关系
- 级联操作
-
事务与连接池
- 事务管理
- 使用连接池提高性能
-
高级功能
- 查询构造器与过滤器
- 自定义查询与聚合操作
1. SQLAlchemy 基础
安装 SQLAlchemy
通过 pip
安装 SQLAlchemy:
pip install sqlalchemy
对于 MySQL 或 PostgreSQL 这样的数据库,你还需要安装相应的驱动程序:
pip install pymysql # 对于 MySQL
pip install psycopg2 # 对于 PostgreSQL
创建数据库连接
SQLAlchemy 的基础在于创建与数据库的连接,你可以通过 create_engine()
函数来创建引擎对象,它代表了数据库连接的核心。
- 连接 SQLite 数据库(SQLite 是一个轻量级数据库,适用于小型项目):
from sqlalchemy import create_engine# 创建 SQLite 引擎
engine = create_engine('sqlite:///example.db', echo=True)
- 连接 MySQL 数据库:
engine = create_engine('mysql+pymysql://username:password@localhost/mydatabase')
- 连接 PostgreSQL 数据库:
engine = create_engine('postgresql+psycopg2://username:password@localhost/mydatabase')
echo=True
会打印生成的 SQL 语句,帮助调试。
使用 SQLAlchemy Core 执行原生 SQL 查询
除了 ORM,SQLAlchemy 还提供了 Core API,用于直接执行 SQL 查询。
- 创建表:
from sqlalchemy import MetaData, Table, Column, Integer, Stringmetadata = MetaData()# 定义表结构
users_table = Table('users', metadata,Column('id', Integer, primary_key=True),Column('name', String),Column('age', Integer)
)# 创建表
metadata.create_all(engine)
- 插入数据:
from sqlalchemy import insert# 插入数据
stmt = insert(users_table).values(name='Alice', age=25)
with engine.connect() as conn:conn.execute(stmt)
- 查询数据:
from sqlalchemy import select# 查询数据
stmt = select(users_table)
with engine.connect() as conn:result = conn.execute(stmt)for row in result:print(row)
- 更新与删除数据:
from sqlalchemy import update, delete# 更新数据
stmt = update(users_table).where(users_table.c.name == 'Alice').values(age=30)
with engine.connect() as conn:conn.execute(stmt)# 删除数据
stmt = delete(users_table).where(users_table.c.name == 'Alice')
with engine.connect() as conn:conn.execute(stmt)
2. ORM 基础
定义模型(Classes as Tables)
在 SQLAlchemy ORM 中,表结构通过 Python 类表示。每个类代表数据库中的一张表,类的属性代表表中的列。
- 定义模型类:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, StringBase = declarative_base()class User(Base):__tablename__ = 'users' # 表名id = Column(Integer, primary_key=True)name = Column(String)age = Column(Integer)def __repr__(self):return f"<User(name={self.name}, age={self.age})>"
创建表结构
使用 Base.metadata.create_all()
创建模型类对应的表结构。
Base.metadata.create_all(engine)
插入、查询、更新、删除数据
- 创建数据库会话:
为了与数据库交互,SQLAlchemy 使用会话(Session)对象。它是数据库连接的一个高层次接口。
from sqlalchemy.orm import sessionmakerSession = sessionmaker(bind=engine)
session = Session()
- 插入数据:
# 插入数据
new_user = User(name='Bob', age=22)
session.add(new_user)
session.commit()
- 查询数据:
# 查询所有用户
users = session.query(User).all()
for user in users:print(user)# 查询特定条件的数据
user = session.query(User).filter_by(name='Bob').first()
print(user)
- 更新数据:
# 更新 Bob 的年龄
user = session.query(User).filter_by(name='Bob').first()
user.age = 23
session.commit()
- 删除数据:
# 删除用户
user = session.query(User).filter_by(name='Bob').first()
session.delete(user)
session.commit()
3. 关系映射
一对多关系
在数据库中,一对多关系是非常常见的。可以使用 SQLAlchemy 定义这样的关系,例如,一个用户可以有多个地址。
- 定义一对多关系:
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationshipclass Address(Base):__tablename__ = 'addresses'id = Column(Integer, primary_key=True)email = Column(String)user_id = Column(Integer, ForeignKey('users.id'))user = relationship('User', back_populates='addresses')User.addresses = relationship('Address', order_by=Address.id, back_populates='user')
在这个模型中,User
与 Address
之间建立了一对多的关系。
- 插入与查询关系数据:
new_user = User(name='Charlie', age=30)
new_address = Address(email='charlie@example.com', user=new_user)session.add(new_user)
session.add(new_address)
session.commit()# 查询用户及其地址
user = session.query(User).filter_by(name='Charlie').first()
print(user.addresses) # 输出用户的地址列表
多对多关系
在多对多关系中,两个表之间通过一个中间表来关联。
- 定义多对多关系:
from sqlalchemy import Tableassociation_table = Table('association', Base.metadata,Column('user_id', Integer, ForeignKey('users.id')),Column('group_id', Integer, ForeignKey('groups.id'))
)class Group(Base):__tablename__ = 'groups'id = Column(Integer, primary_key=True)name = Column(String)User.groups = relationship('Group', secondary=association_table, back_populates='users')
Group.users = relationship('User', secondary=association_table, back_populates='groups')
- 插入与查询多对多关系数据:
# 创建用户与群组
new_group = Group(name='Admins')
new_user = User(name='Alice', age=25)
new_user.groups.append(new_group)session.add(new_user)
session.commit()# 查询用户的群组
user = session.query(User).filter_by(name='Alice').first()
print(user.groups) # 输出用户所在的群组
级联操作
级联操作可以在删除或更新主表数据时自动影响相关的表。可以通过 cascade
参数来控制级联行为。
- 定义级联删除:
User.addresses = relationship('Address', back_populates='user', cascade='all, delete-orphan')
此设置意味着如果删除一个 User
,它的 Address
记录也会被删除。
4. 事务与连接池
事务管理
在数据库操作中,事务管理非常重要,尤其是在处理批量插入、更新和删除时。
- 手动管理事务:
session = Session()try:new_user = User(name='David', age=35)session.add(new_user)session.commit()
except:session.rollback() # 如果出现错误,回滚事务raise
finally:session.close()
使用连接池提高性能
SQLAlchemy 提供了对数据库连接池的支持,以提高数据库访问的性能。你可以通过在创建引擎时指定连接池配置来管理连接。
- 设置连接池:
engine = create_engine('mysql+pymysql://username:password@localhost/mydatabase',pool_size=5, # 连接池的大小max_overflow=10, # 当连接池用尽时,最多允许额外创建的连接数pool_timeout=30, # 等待连接池的超时时间(秒)pool_recycle=3600 # 每隔一小时回收一次连接,以避免长时间的空闲连接
)
这种配置可以防止频繁建立和关闭数据库连接,尤其在需要高效访问数据库的场景中极为重要。
5. 高级功能
查询构造器与过滤器
SQLAlchemy ORM 提供了丰富的查询构造功能,使得我们能够以面向对象的方式生成复杂的查询。以下是一些常用的查询构造方式:
- 查询所有记录:
users = session.query(User).all()
for user in users:print(user)
- 过滤查询:
# 按名字过滤
users = session.query(User).filter_by(name='Alice').all()# 使用条件表达式
users = session.query(User).filter(User.age > 30).all()
- 排序与限制:
# 按年龄排序
users = session.query(User).order_by(User.age).all()# 只返回前 5 个用户
users = session.query(User).limit(5).all()
- 联接查询(查询多个表):
# 查询用户和他们的地址
results = session.query(User, Address).join(Address).all()
for user, address in results:print(f'{user.name} lives at {address.email}')
- 计数、求和与聚合操作:
from sqlalchemy import func# 计算用户数量
user_count = session.query(func.count(User.id)).scalar()# 计算用户的平均年龄
average_age = session.query(func.avg(User.age)).scalar()
自定义查询与聚合操作
SQLAlchemy 的 func
模块使得我们能够使用数据库中的聚合函数,如 COUNT
、SUM
、MAX
等。
- 聚合查询:
# 查询用户的最大年龄
max_age = session.query(func.max(User.age)).scalar()# 计算特定条件下的总人数
count = session.query(func.count(User.id)).filter(User.age > 30).scalar()
原生 SQL 查询
如果需要执行复杂的原生 SQL 查询,SQLAlchemy 也提供了直接执行原生 SQL 的能力。
- 执行原生 SQL:
result = session.execute('SELECT * FROM users WHERE age > :age', {'age': 30})
for row in result:print(row)
通过这种方式,你可以自由使用数据库特有的 SQL 语句。
结论
通过本教程,你已经详细了解了 SQLAlchemy 的基本与高级功能,从建立数据库连接、创建表结构、到复杂的查询与事务管理等。SQLAlchemy 提供了两种主要的使用模式:
- SQLAlchemy Core:用于执行原生 SQL 操作,适用于需要精准控制数据库查询的场景。
- SQLAlchemy ORM:为开发者提供了更加 Pythonic 的方式来管理数据库模型,隐藏了 SQL 复杂性,更适合业务逻辑开发。
相关文章:

Python 课程18-SQLAlchemy
前言 SQLAlchemy 是一个功能强大的 Python SQL 工具包和对象关系映射(ORM)库,它使得开发者能够通过 Python 代码与数据库进行交互,而不必编写 SQL 查询。SQLAlchemy 提供了对多种数据库的支持,包括 MySQL、PostgreSQL…...

Module did not self-register: ‘drivelist.node‘报错解决
报错如下: node_modules/bindings/bindings.js:121throw e;^Error: Module did not self-register: xxxx/node_modules/drivelist/build/Release/drivelist.node.at process.func [as dlopen] (electron/js2c/asar.js:140:31)at Object.Module._extensions..node (…...

zabbix基本概念与组件
文章目录 一、zabbix简介二、zabbix构成三、zabbix监控对象四、zabbix常用术语五、 Zabbix 6.0 新特性1.Zabbix server高可用防止硬件故障或计划维护期的停机2.Kubernetes系统从多个维度采集指标 六、zabbix 工作原理1、主动模式2、…...
Linux常用网络工具及示例
Linux系统中有许多用于网络管理、监控和故障排除的工具。以下是一些常用的网络工具及其基本用法示例: 1. ping - 测试主机之间的网络连接。 ping www.google.com 2. netstat - 显示网络连接、路由表、接口统计等信息。 netstat -an # 显示所有网络连接和监听…...

Go容器化微服务系统实战
1-1 本课的go微服务有什么不同? 聚焦于容器化可观测的购物微服务系统实战,通过介绍Go语言的应用趋势、容器化优势及微服务适用性,旨在解决学习微服务过程中遇到的难点。课程内容涵盖微服务整体架构、技术工具框架及容器平台等关键技术&#…...
研究生三年概括
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、研一1.上学期2. 下学期 二、研二1.研二上2.研二下 三、研三1.研三上2.研三下 前言 不知道是谁说的了,人生的路很长,关键的就那么几…...

MongoDB在Linux系统中的安装与配置指南
在这篇文章中,我们将介绍如何在CentOS 7服务器上安装MongoDB,并通过DataX将数据从MongoDB迁移到MySQL数据库。这将包括MongoDB的安装、配置、数据准备以及使用DataX进行数据迁移的详细步骤。 MongoDB简介 MongoDB是一个高性能、开源、无模式的文档型数据…...
Linux下如何实现不用加路径调用启动脚本
配置Systemctl启动 Linux下便于启停服务,可以配置systemcl,配置如下描述 说明 只有root用户可配置,文件路径为 /etc/systemd/system/XXX.service,本文将用nginx.service举例说明 1、创建文件 首先创建一个nginx.service文件,用于配置ngi…...

编程练习2 数据单元的变量替换
示例1: 1,2<A>00 示例2: 1,2<A>00,3<A>00 示例3: <B>12,1,2<B>1 示例4: <B<12,1 输出依次如下: #include<iostream> #include<vector> #include<string>using namespace std;/* 字符分割函数 将传入…...
mysql的查询操作
MySQL的查询操作是数据库管理和数据检索的核心。通过SQL(Structured Query Language,结构化查询语言)语句,用户可以执行包括数据检索、数据插入、更新和删除在内的多种操作。在本文中,我们将重点讨论数据检索ÿ…...
0基础学前端 day2
大家好,欢迎来到无限大的频道。 今天继续带领大家开始0基础学前端。 一、CSS简介与基础 层叠样式表(CSS,Cascading Style Sheets)是用来进行网页样式和布局设计的语言。通过CSS,开发者可以控制网页中元素的颜色、字体…...

Invalid Executable The executable contains bitcode
Invalid Executable The executable contains bitcode xcode世界xcode16后,打包上传testflight时三方库报错:Invalid Executable - The executable ***.app/Frameworks/xxx.framework/xxx contains bitcode. 解决方案: 执行一下指令删除该f…...

音视频入门基础:FLV专题(4)——使用flvAnalyser工具分析FLV文件
一、引言 有很多工具可以分析FLV格式,这里推荐flvAnalyser。其支持: 1.FLV 文件分析(Tag 列表、时间戳、码率、音视频同步等),HEVC(12)/AV1(13) or Enhanced RTMP v1 with fourCC(hvc1/av01); 2.RTMP/HTT…...
Java服务端开发中的网络安全:防护DDoS与数据泄露的策略
Java服务端开发中的网络安全:防护DDoS与数据泄露的策略 大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在Java服务端开发中,网络安全是我们必须重点关注的领域,…...
CodeMeter 8.20AxProtector 11.50版本更新
CodeMeter是一款强大的软件保护和许可管理工具,此次8.20版本更新引入了多个重要的新功能和优化,进一步提升了不同平台上的兼容性与使用体验。本次更新扩展了对CmCloudContainer的支持,优化了Python、Rust等语言的加密能力,并修复了…...
C语言在嵌入式系统中的应用有哪些?
C语言在嵌入式系统中的应用非常广泛,这主要得益于其高效的运行速度、优秀的代码优化能力以及丰富的函数库。以下是C语言在嵌入式系统应用中的几个关键方面: 1. 硬件直接访问能力 底层硬件操作:C语言提供了直接访问底层硬件的机制࿰…...
Android 系统WIFI AP模式
在 Android 系统中,AP 模式(Access Point Mode,热点模式)允许设备作为 Wi-Fi 热点,其他设备可以通过连接这个热点进行互联网访问或局域网通信。要让 Android 设备工作在 AP 模式,你可以通过应用层的 API 控…...
java jdk8内存序列化为xml
在Java JDK 8中,将对象内存序列化为XML格式,可以使用JAXB(Java Architecture for XML Binding),它是JDK 8的一部分,并且被广泛用于Java对象与XML之间的转换。以下是一个使用JAXB在JDK 8中将Java对象序列化为…...

脚本注入网页:XSS
跨站脚本攻击(Cross-Site Scripting,简称 XSS)是一种常见的网络安全漏洞。它是指攻击者在网页中注入恶意脚本代码,当用户访问该网页时,恶意脚本会在用户的浏览器中执行,从而导致一系列安全问题。这些问题可…...
Python将ONNX转为Json脚本
Python脚本 import onnx from onnx.shape_inference import infer_shapes import numpy as npfrom google.protobuf.json_format import MessageToJson, Parse import argparse import osdef convertToJson(onnx_model_path):onnx_model = onnx.load(onnx_model_path)message …...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...

论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...