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内生智能架构将成为重要研究方向,实现低延迟、高效率的智能通信。信息编码与调制技术:新型…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...
jdbc查询mysql数据库时,出现id顺序错误的情况
我在repository中的查询语句如下所示,即传入一个List<intager>的数据,返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致,会导致返回的id是从小到大排列的,但我不希望这样。 Query("SELECT NEW com…...
密码学基础——SM4算法
博客主页:christine-rr-CSDN博客 专栏主页:密码学 📌 【今日更新】📌 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 编辑…...
