python深入SQLAlchemy使用详解
上次发布《多种方式访问mysql的对比分析》一文后,有读者留言,说SQLAlchemy的使用方法没讲清楚,只有一段简短的介绍,演示代码也比较模糊,SQLAlchemy在实际项目运用非常广泛,由于其支持 ORM 模型,能够将表映射为类,让你用Python类的方式来操作数据库,而不需要直接写SQL语句,是面向对象访问数据库不可或缺的一个库,根据需求设计数据库结构和操作逻辑,可以大大提高开发效率和代码可维护性。今天风云将该库的详细使用方法重新整理了,发出来,供大家参考,欢迎留言讨论。
为什么还要用SQLAlchemy呢?原因有几个:
1.简洁:SQLAlchemy让你用Python代码来操作数据库,代码更简洁,也更容易理解。
2.安全:它能帮助你避免SQL注入等安全问题,让你的数据库更安全。
3.灵活:SQLAlchemy支持多种数据库(比如MySQL、PostgreSQL、SQLite等),你只需要改一下配置,就能在不同的数据库之间切换。
SQLAlchemy 包括两个核心组件:
- SQLAlchemy Core:提供底层 SQL 构造和数据库连接。
- SQLAlchemy ORM:实现面向对象的 ORM 映射。
1. 安装 SQLAlchemy
使用 pip 安装:
pip install sqlalchemy
2. 数据库连接
使用 create_engine 创建数据库连接:
from sqlalchemy import create_engine
# 替换为实际的数据库 URL
engine = create_engine('sqlite:///example.db') # SQLite 示例
# MySQL 示例: 'mysql+pymysql://user:password@host/dbname'
3. 使用 SQLAlchemy Core
3.1 创建表
使用 MetaData 和 Table 定义表结构:
from sqlalchemy import Table, Column, Integer, String, MetaData,create_engineengine = create_engine('sqlite:///example.db') # SQLite 示例数据库
metadata = MetaData() # 元数据对象users = Table( # 创建表'users', metadata, # 表名Column('id', Integer, primary_key=True), # id字段Column('name', String(50)), # name字段Column('age', Integer) # age字段
)metadata.create_all(engine) # 创建表
3.2 插入数据
使用 insert() 插入数据:
from sqlalchemy import insertwith engine.connect() as conn: # 连接数据库stmt = insert(users).values(name='Alice', age=30) # 插入数据conn.execute(stmt) # 执行插入语句
3.3 查询数据
使用 select() 查询:
from sqlalchemy import selectwith engine.connect() as conn: # 连接数据库stmt = select(users) # 查询数据result = conn.execute(stmt) # 执行查询语句for row in result: # 遍历结果print(row)
4. 使用 SQLAlchemy ORM
4.1 定义模型
使用 ORM 的 declarative_base 定义模型:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, StringBase = declarative_base() # 创建基类class User(Base): # 创建User类__tablename__ = 'users' # 表名id = Column(Integer, primary_key=True) # id字段name = Column(String(50)) # name字段age = Column(Integer) # age字段
4.2 创建表
创建表结构:
Base.metadata.create_all(engine)
4.3 创建会话
使用 sessionmaker 创建会话:
from sqlalchemy.orm import sessionmakerSession = sessionmaker(bind=engine) # 创建Session会话类
session = Session()
4.4 增删改查
插入数据
new_user = User(name='Bob', age=25) # 创建新用户session.add(new_user)# 添加新用户到sessionsession.commit() # 提交事务
查询数据
users = session.query(User).all() # 查询所有用户
for user in users: # 遍历查询结果print(user.name, user.age)
更新数据
user = session.query(User).filter_by(name='Bob').first() # 查询用户
user.age = 26session.commit() # 提交事务
删除数据
user = session.query(User).filter_by(name='Bob').first() # 查询具体用户,定位到第一条记录session.delete(user) # 删除用户
session.commit() # 提交事务
5. 使用关系映射
定义一对多关系:
from sqlalchemy import ForeignKeyfrom sqlalchemy.orm import relationshipclass Post(Base):__tablename__ = 'posts' # 表名id = Column(Integer, primary_key=True) # id字段title = Column(String(100)) # title字段user_id = Column(Integer, ForeignKey('users.id')) # 定义外键user = relationship('User', back_populates='posts') # 关联关系User.posts = relationship('Post', order_by=Post.id, back_populates='user') # 关联关系# 插入关联数据:
user = User(name='Charlie')post1 = Post(title='Post 1', user=user)post2 = Post(title='Post 2', user=user)session.add(user) # 添加关联数据session.add_all([post1, post2]) # 添加所有关联session.commit() # 提交事务#查询关联数据:
user = session.query(User).filter_by(name='Charlie').first() # 查询关联数据for post in user.posts: # 遍历关联数据print(post.title)
6. 使用事务
手动管理事务:
from sqlalchemy.exc import SQLAlchemyErrortry:with session.begin(): # 开启事务user = User(name='Dave', age=40) # 创建新用户session.add(user) # 添加新用户到session
except SQLAlchemyError as e: # 如果发生异常,回滚事务print(f"Transaction failed: {e}")session.rollback() # 回滚事务
7. 完整的封装类
最后,风云按惯例将此使用封装为一个完整的类,大家有需要有的自取
from sqlalchemy import create_engine, Column, Integer, String, exc
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmakerBase = declarative_base() # 创建基类# 定义表模型
class User(Base):__tablename__ = 'users' # 表名id = Column(Integer, primary_key=True, autoincrement=True) # id字段name = Column(String(50), nullable=False) # name字段age = Column(Integer, nullable=False) # age字段class MySQLHandler:def __init__(self, user, password, host, database):"""初始化数据库连接和会话"""try:url = f'mysql+pymysql://{user}:{password}@{host}/{database}' # 创建数据库连接self.engine = create_engine(url, echo=False) # 数据库引擎Base.metadata.create_all(self.engine) # 创建表self.Session = sessionmaker(bind=self.engine) # 创建会话except exc.SQLAlchemyError as e:print(f"Error initializing database: {e}")def add_user(self, name, age):"""添加用户"""session = self.Session() try:new_user = User(name=name, age=age) # 创建新用户session.add(new_user) # 添加新用户到sessionsession.commit() # 提交事务print(f"User {name} added successfully!")except exc.SQLAlchemyError as e: # 如果发生异常,回滚事务session.rollback() # 执行回滚print(f"Error adding user: {e}")finally:session.close() # 关闭会话def get_users(self):"""查询所有用户"""session = self.Session()try:users = session.query(User).all() # 查询所有用户return [{"id": user.id, "name": user.name, "age": user.age} for user in users]except exc.SQLAlchemyError as e: # 如果发生异常,返回空print(f"Error fetching users: {e}")return []finally:session.close()def update_user(self, user_id, name=None, age=None):"""更新用户信息"""session = self.Session()try:user = session.query(User).filter_by(id=user_id).first() # 查询用户if not user: # 如果用户不存在,返回print(f"User with ID {user_id} not found.")returnif name:user.name = nameif age:user.age = agesession.commit() # 提交事务print(f"User {user_id} updated successfully!")except exc.SQLAlchemyError as e: # 如果发生异常,回滚事务session.rollback()print(f"Error updating user: {e}")finally:session.close()def delete_user(self, user_id):"""删除用户"""session = self.Session()try:user = session.query(User).filter_by(id=user_id).first() # 查询用户if not user: # 如果用户不存在,返回print(f"User with ID {user_id} not found.")returnsession.delete(user) # 删除用户session.commit() # 提交事务print(f"User {user_id} deleted successfully!")except exc.SQLAlchemyError as e: # 如果发生异常,回滚事务session.rollback()print(f"Error deleting user: {e}")finally:session.close()def transaction_example(self):"""事务操作示例"""session = self.Session()try:user1 = User(name="Alice", age=30) # 创建2个新用户user2 = User(name="Bob", age=25) # 添加多个用户session.add(user1) # 添加新用户到sessionsession.add(user2)# 模拟事务中的错误# Uncomment the line below to raise an exception and trigger a rollback# raise ValueError("Simulated error!")session.commit() # 提交事务print("Transaction completed successfully!")except (exc.SQLAlchemyError, ValueError) as e: # 如果发生异常,回滚事务session.rollback()print(f"Transaction failed: {e}")finally:session.close()# 使用示例
if __name__ == "__main__":# 初始化数据库连接db_handler = MySQLHandler(user='root', password='password123', host='localhost', database='test_db')# 添加用户db_handler.add_user(name="John Doe", age=28)# 查询用户users = db_handler.get_users()print("Users:", users)# 更新用户db_handler.update_user(user_id=1, name="Jane Doe", age=32)# 删除用户db_handler.delete_user(user_id=1)# 事务示例db_handler.transaction_example()
相关文章:
python深入SQLAlchemy使用详解
上次发布《多种方式访问mysql的对比分析》一文后,有读者留言,说SQLAlchemy的使用方法没讲清楚,只有一段简短的介绍,演示代码也比较模糊,SQLAlchemy在实际项目运用非常广泛,由于其支持 ORM 模型,…...
Bootstrap4 模态框
Bootstrap4 模态框 Bootstrap 是一个流行的前端框架,它可以帮助开发者快速构建响应式、移动设备优先的网站和应用程序。Bootstrap 4 是其最新版本,提供了许多易于使用的组件,其中模态框(Modal)组件是其中之一。本文将详细介绍 Bootstrap 4 模态框的用法、特性和优化技巧。…...
GSI快速收录服务:让你的网站内容“上架”谷歌
辛苦制作的内容无法被谷歌抓取和展示,导致访客无法找到你的网站,这是会让人丧失信心的事情。GSI快速收录服务就是为了解决这种问题而存在的。无论是新上线的页面,还是长期未被收录的内容,通过我们的技术支持,都能迅速被…...
vim如何设置制表符表示的空格数量
:set tabstop4 设置制表符表示的空格数量 制表符就是tab键,一般默认是四个空格的数量 示例: (vim如何使设置制表符表示的空格数量永久生效:vim如何使相关设置永久生效-CSDN博客)...
【Uniapp-Vue3】setTabBar设置TabBar和下拉刷新API
一、setTabBar设置 uni.setTabBarItem({ index:"需要修改第几个", text:"修改后的文字内容" }) 二、tabBar的隐藏和显式 // 隐藏tabBar uni.hideTabBar(); // 显示tabBar uni.showTabBar(); 三、为tabBar右上角添加文本 uni.setTabBarBadge({ index:"…...
【玩转全栈】----Django模板的继承
先赞后看,养成习惯!!! 目录 模板继承的好处 模板继承的语法规则 更新代码 上文中的部门管理页面: 【玩转全栈】----Django制作部门管理页面-CSDN博客 大家会发现,由于定义了多个html文件,多个ht…...
详解数据库系统概述
数据库系统概述 1. 数据库(Database)1.1 定义:1.2 特点:1.3 举例: 2. 数据库管理系统(DBMS:Database Management System)2.1 定义:2.2 DBMS 的主要功能:2.3 常…...
Windows的docker中安装gitlab
一.Windows的docker中安装gitlab 1.通过阿里云拉取镜像 docker pull registry.cn-hangzhou.aliyuncs.com/lab99/gitlab-ce-zh 2.在本地创建备份数据的目录 mkdir -p D:home/software/gitlab/etc mkdir -p D:home/software/gitlab/logs mkdir -p D:home/software/gitlab/dat…...
基于微信小程序的健身管理系统设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
windows 安装 mysql 教程
一、下载 点开下面的链接: https://downloads.mysql.com/archives/community/ 点击Download 就可以下载对应的安装包了, 安装包如下: 二、解压 下载完成后我们得到的是一个压缩包,将其解压,我们就可以得到MySQL 8.0.28 的软件本体了(就是…...
Vue2+OpenLayers初始化高德地图
目录 一、案例截图 二、完整代码 一、案例截图 二、完整代码 一键复制即可运行: <template><div id"map-container"></div> </template> <script> import { Map, View } from ol import { Tile as TileLayer } from ol…...
六、深入了解DI
依赖注入是⼀个过程,是指IoC容器在创建Bean时,去提供运⾏时所依赖的资源,⽽资源指的就是对象. 在上⾯程序案例中,我们使⽤了 Autowired 这个注解,完成了依赖注⼊的操作. 简单来说,就是把对象取出来放到某个类的属性中。 关于依赖注…...
IMX6ull项目环境配置
文件解压缩: .tar.gz 格式解压为 tar -zxvf .tar.bz2 格式解压为 tar -jxvf 2.4版本后的U-boot.bin移植进SD卡后,通过串口启动配置开发板和虚拟机网络。 setenv ipaddr 192.168.2.230 setenv ethaddr 00:04:9f:…...
Edge-TTS在广电系统中的语音合成技术的创新应用
Edge-TTS在广电系统中的语音合成技术的创新应用 作者:本人是一名县级融媒体中心的工程师,多年来一直坚持学习、提升自己。喜欢Python编程、人工智能、网络安全等多领域的技术。 摘要 随着人工智能技术的快速发展,文字转语音(Te…...
芸众商城小程序会员页面部分图标不显示问题解决办法
我遇到的问题 如下图所示,会员中心这里的图标在小程序端显示异常。但是在网页端又是能够正常显示的。 小程序端截图: 网页端截图: 我的解决方法 检查使用的小程序版本,比如这里使用的是1.2.238版本的小程序,最后…...
手机app如何跳过无障碍权限实现弹框自动点击-ADB连接专题
手机app如何跳过无障碍权限实现弹框自动点击 --ADB连接专题 一、前言 我们在前期的时候,在双SIM卡进行协同外呼和SIM卡切换时,对如何在手机中“执行批处理脚本做自动点击”的内容进行预研,力图使用事件触发和坐标点击等方式来实现手机安装…...
「 机器人 」扑翼飞行器控制的当前挑战与后续潜在研究方向
前言 在扑翼飞行器设计与控制方面,虽然已经取得了显著的进步,但在飞行时间、环境适应性、能量利用效率及模型精度等方面依旧存在亟待解决的挑战。以下内容概括了这些挑战和可能的改进路径。 1. 当前挑战 1.1 飞行时间短 (1)主要原因 能源存储有限(电池容量小)、驱动系…...
Vue入门(Vue基本语法、axios、组件、事件分发)
Vue入门 Vue概述 Vue (读音/vju/,类似于view)是一套用于构建用户界面的渐进式框架,发布于2014年2月。与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,不仅易于上手,还便于与第三…...
DELL EDI:需求分析及注意事项
Dell 的 EDI 需求分析 1.对接 Dell 需要使用的 EDI 传输协议 Dell 支持的传输方式包括: AS2(Applicability Statement 2):主要用于安全可靠的数据传输,在使用 AS2 时,所有数据都通过 HTTPS 或 HTTP 协议…...
计算机网络 (62)移动通信的展望
一、技术发展趋势 6G技术的崛起 内生智能:6G将强调自适应网络架构,通过AI驱动的智能算法提升通信能力。例如,基于生成式AI的6G内生智能架构将成为重要研究方向,实现低延迟、高效率的智能通信。信息编码与调制技术:新型…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
