SQLAlchemy ORM指南:简化数据库操作的最佳实践

SQLAIchemy 开发指南

背景:

​ SQLAlchemy是一个数据库的ORM框架,让我们操作数据库的时候不要再用SQL语句了,跟直接操作模型一样。操作十分便捷,其实SQLAlchemy应该是在Flask和Django应用的特别多,而且在flask中已经集成了flask_sqlalchemy ,好像是 SQLAlchemy的作者和 Flask是同一个,背景了解到这里就可以啦,接下来为大家讲一讲。

环境安装:

pip install SQLAlchemy
conda  install SQLAlchemy

当然了你还需要配置好数据库mysql或者mongodb,sqlite等等。

测试连接:

# -*- coding: utf-8 -*-            
from sqlalchemy import create_engine
from sqlalchemy import text
# MySQL所在的主机名
HOSTNAME = "127.0.0.1"
# MySQL监听的端口号,默认3306
PORT = 13306
# 连接MySQL的用户名,读者用自己设置的
USERNAME = "root"
# 连接MySQL的密码,读者用自己的
PASSWORD = "xxxxx"
# MySQL上创建的数据库名称
DATABASE = "learning"
DB_URI = f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}"
# 创建数据库引擎
engine = create_engine(DB_URI)
# 所有的类都要继承自`declarative_base`这个函数生成的基类
Base = declarative_base(engine)
#创建连接
with engine.connect() as con:rs = con.execute('SELECT 1')# 如果报错的话,加上text() 就不会报错。# rs = con.execute(text('SELECT 1'))print(rs.fetchone())

在这里插入图片描述

首先从sqlalchemy中导入create_engine,用这个函数来创建引擎,然后用engine.connect()来连接数据库。但是创造引擎要满足固定的格式:db+driver(驱动)😕/username:password@host:port/database?charset=utf8

  • db 为数据库类型,MySQL、PostgreSQL、SQLite,并且转换成小写。
  • driver 就是驱动,python会有一些第三方扩展包,连接数据库 ,如果不指定,会选择默认的驱动,MySQL常用的驱动右Mysqldb,pymysql,这里建议大家使用pymysql因为mysqldb这个包很容易报错,版本容易不匹配。
  • username是连接数据库的用户名
  • password是连接数据库的密码
  • host是连接数据库的域名
  • port是数据库监听的端口号
  • database是连接哪个数据库的名字。

这里为大家主要讲解的是mysql结合SQL alchemy的使用。

原生查询:

#创建连接
with engine.connect() as con:# rs = con.execute(text('SELECT 1'))rs=con.execute("show tables")print(rs.fetchall())

在这里插入图片描述

创建表:

class User(Base):# 定义表名为users__tablename__ = 'users'# 将id设置为主键,并且默认是自增长的id = Column(Integer, primary_key=True, autoincrement=True)# name字段,字符类型,最大的长度是50个字符name = Column(String(50))fullname = Column(String(50))password = Column(String(100))# 修改内置方法def __str__(self):return "<User(id='%s',name='%s',fullname='%s',password='%s')>" % (self.id, self.name, self.fullname, self.password)# 执行提交命令
Base.metadata.create_all()

我们回到数据库查看发现,自动生成了一张表:

在这里插入图片描述

添加数据:

# 对于数据的增减删查 我们依靠session对象,session即会话对象
Session = sessionmaker(bind=engine)#  创建以一个会话对象
session = Session()
# 创建一个对象
ed_user = User(name='hbhh', fullname='Ed Jones', password='123456')  #
# 添加到会话
session.add(ed_user)
# 添加到数据库
session.commit()

在这里插入图片描述

关于会话的理解:

​ 可能大家有这样的疑问?为什么我要想对会话做操作,然后在对数据库进行修改呢,个人的理解是因为安全,就是假如我们真的做错了,数据库信息已经改变了,那么我们只能对数据库进行修改了,这显然不符合软件开发,如果我前面做错了,我可以回滚啊,就是撤销的意思,会话就是一个很好的解决方式,我们可以先将操作提交到缓存上,然后再对数据库进行相应的操作。

# 创建一个新的用户
fake_user = User(name='fakeuser',fullname='Invalid',password='12345')
session.add(fake_user)
# 判断`fake_user`是否在`session`中存在
print(fake_user in session) # True
session.rollback() # 回滚
print(fake_user in session) # False 

​ 但是你到数据库是查不到这个fake_user的,因为之前说了目前只在session层面做了操作,没用对数据库做操作,所以你也找不到。

查询:

for demo in session.query(User).order_by(User.id).all():
# all() 是获取所有结果集 one() 是获取一个print(demo)

在这里插入图片描述

for instance in session.query(User.name).all():print(instance)

在这里插入图片描述

for instance in session.query(User.name,User.fullname).all():print(instance) # 输出所有的查找结果

在这里插入图片描述

过滤查询:

​ 如果想对结果进行过滤,可以使用filter_by和filter两个方法,这两个方法都是用来做过滤的,区别在于,filter_by是传入关键字参数,filter是传入条件判断,并且filter能够传入的条件更多更灵活。

# query() 参数就是想要的结果
for name in session.query(User.name).filter_by(fullname='Kong Ziyi').all():print(name)
for name in session.query(User.name).filter(User.fullname=='Kong Ziyi').all():print(name)

在这里插入图片描述

过滤条件:

相等:

query.filter(User.name == 'ed')

不相等:

query.filter(User.name != 'ed')

模糊:

query.filter(User.name.like('%ed%'))
for user in session.query(User).filter(User.name.like('%o%')).all():print(user)

在这里插入图片描述

在:

query.filter(User.name.in_(['ed','Venti','Klee']))# 同时,in也可以作用于一个Query
query.filter(User.name.in_(session.query(User.name).filter(User.name.like('%o%'))))

不在:

query.filter(~User.name.in_(['ed','Venti','Klee']))
print(session.query(User).filter(~User.name.in_(['ed','Venti','Klee'])))

空值:

query.filter(User.name==None)# 或者是
query.filter(User.name.is_(None))

非空:

query.filter(User.name != None)# 或者是
query.filter(User.name.isnot(None))

与:

from sqlalchemy import and_
query.filter(and_(User.name=='ed',User.fullname=='Ed Jones'))# 或者是传递多个参数
query.filter(User.name=='ed',User.fullname=='Ed Jones')# 或者是通过多次filter操作
query.filter(User.name=='ed').filter(User.fullname=='Ed Jones')

或者:

from sqlalchemy import or_  
query.filter(or_(User.name=='ed',User.name=='Venti'))
结果筛选:
query = session.query(User).filter(User.name.like('%o%')).order_by(User.id)
print(query.all()) # 结果集全部
# print(query.one())  # 结果集只有一个才能用,不然会报错
print(query.first()) # 结果集第一个
print(query.count()) # 结果集数量
session.query(User).filter(User.name.like('%ed%')).count()

在这里插入图片描述

聚合查询:

group_by(分组字段)

from sqlalchemy import func
# query(func.count(User.name),User.name) 两个参数 就相当于sql 得到的两个查询字段
for user in session.query(func.count(User.name),User.name).group_by(User.name).all():print(user,type(user))

在这里插入图片描述

session.query(User.gender,func.count(User.id)).group_by(User.gender).all()

温馨提示:

所有的查询得到:都是类似一个sql语句的东西:如下

print(session.query(User.name).filter(User.fullname=='Kong Ziyi'))

在这里插入图片描述

如果我们想得到相应的对象,必须加all()、one() 才可以得到真正意义上的对象。

print(session.query(User.name).filter(User.fullname=='Kong Ziyi').one())

在这里插入图片描述

文本SQL:

SQLAlchemy还提供了使用****文本SQL****的方式来进行查询,这种方式更加的灵活。与数据库对接比较紧密。

但是需要将sql语句放在text() 中。

from sqlalchemy import text
from sqlalchemy import text
# text() 中的内容 就是sql语句
for user in session.query(User).filter(text("id<10")).order_by(text("id")).all():print(user.name)

在这里插入图片描述

上面这种写法有一个缺陷就是写死了,如果我们传递的是一个变量呢?

session.query(User).filter(text("id<:value and name=:name")).params(value=224,name='ed').order_by(User.id)
# value是变量  name也是变量

在文本SQL中的变量前面使用了:来区分,然后使用params方法,指定需要传入进去的参数。

这样的写法有一点麻烦,及要写过滤的函数还要写 条件函数,我们可以采取下面分方法:

sesseion.query(User).from_statement(text("select * from users where name=:name")).params(name='ed').all()
for user in session.query(User).from_statement(text("select * from users where name=:name")).params(name='hbhh').all():print(user)

在这里插入图片描述

from_statement 返回的是一个text里面的查询语句,最后一定要使用all() ,获取结果集。

Column常用参数:

  • default:默认值。
  • nullable:是否可空。
  • primary_key:是否为主键。
  • nique:是否唯一。
  • autoincrement:是否自动增长。
  • onupdate:更新的时候执行的函数。
  • name:该属性在数据库中的字段映射。

数据类型:

sqlalchemy常用数据类型

  • Integer:整形。
  • Float:浮点类型。
  • Boolean:传递True/False进去。
  • DECIMAL:定点类型。
  • enum:枚举类型。
  • Date:传递datetime.date()进去。
  • DateTime:传递datetime.datetime()进去。
  • Time:传递datetime.time()进去。
  • String:字符类型,使用时需要指定长度,区别于Text类型。
  • Text:文本类型。
  • LONGTEXT:长文本类型。

总结:

​ 在这篇博客中,你详细介绍了 SQLAlchemy 的相关使用,包括增删改查操作以及创建表等内容。这些知识对于学习 Flask 和 Django 构建 Web 应用程序提供了坚实的基础。

​ 通过掌握 SQLAlchemy,你可以更加灵活地操作数据库,轻松实现数据的持久化和查询。这为你开发功能丰富、可靠的 Web 应用程序提供了强大的工具和技术支持。

​ 同时,理解 SQLAlchemy 的工作原理和核心概念,例如 ORM(对象关系映射)模式,可以帮助你更好地组织和管理应用程序的数据层。这样,你可以专注于业务逻辑的开发,而无需过多关注底层数据库的细节。

​ 在未来的学习和实践中,你可以进一步探索 SQLAlchemy 的高级功能和技巧,如复杂查询、关联关系、事务处理等。这些深入的知识将使你能够构建更加灵活、高效的数据库驱动应用程序。

​ 综上所述,通过本文中对 SQLAlchemy 的详细讲解,你已经打下了坚实的基础,为进一步学习和应用 Flask 和 Django 提供了有力的支持。继续努力学习和实践,相信你将在 Web 开发领域取得更大的成就。祝你在未来的学习和项目中取得成功!

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

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

相关文章

Oracle架构_数据库底层原理、机制 (授人以渔)

目录 系统全局区SGA 高速缓存缓冲区(数据库缓冲区) 日志缓冲区 共享池 其他结构 用户连接进程 用户进程User Process Server Process服务进程 程序全局区PGA Oracle的connect连接和session会话与User Process紧密相关 后台进程 数据库写入进程(DBWn) 检查点(CKPT)…

多维时序 | Matlab实现CNN-LSTM-Mutilhead-Attention卷积长短期记忆神经网络融合多头注意力机制多变量时间序列预测

多维时序 | Matlab实现CNN-LSTM-Mutilhead-Attention卷积长短期记忆神经网络融合多头注意力机制多变量时间序列预测 目录 多维时序 | Matlab实现CNN-LSTM-Mutilhead-Attention卷积长短期记忆神经网络融合多头注意力机制多变量时间序列预测效果一览基本介绍程序设计参考资料 效果…

“深入理解 Docker 和 Nacos 的单个部署与集成部署“

目录 引言&#xff1a;Docker Nacos 单个部署1.1 什么是 Docker&#xff1f;Docker 的概念和工作原理Docker 为什么受到广泛应用和认可 1.2 什么是 Nacos&#xff1f;Nacos 的核心功能和特点Nacos 在微服务架构中的作用 1.3 Docker 单个部署 Nacos Docker Nacos 集成部署总结&a…

【重点!!!】【背包】【回溯】518.零钱兑换II

题目 跟39.组合总数、322.零钱兑换题目很类似。 法1&#xff1a;背包DP&#xff0c;最优解法 解释如下&#xff1a; 0 1 2 3 4 5(背包容量)1 0 0 0 0 0 没有硬币的时候&#xff09; 0 1 2 3 4 5(背包容量) 1 1 1 1 1 1 1 0 1 2 3 4 5(背包容量) 1 …

Ubuntu 22.04 安装MySql

MySQL是非常常用的关系型数据库,无论是大厂还是小厂,都有它的身影。最大的优点是免费,安装起来也比较简单。 MySQL的架构 画了个简图,描述了下MySQL的架构。 其中的比较有趣的点在于连接池和存储引擎。连接池缓存了数据库和客户端的TCP连接,以减少建立连接的开销。存储引…

git中合并分支时出现了代码冲突怎么办

目录 第一章、Git代码冲突介绍1.1&#xff09;什么是Git代码冲突①git merge命令介绍②代码冲突原因 1.2&#xff09;提示代码冲突的两种情况①本地不同分支的文件有差异时&#xff1a;②本地仓库和git远程仓库的文件有差异时&#xff1a; 1.3&#xff09;解决合并时的代码冲突…

calloc与realloc和malloc的区别以及new

目录 calloc、realloc 和 malloc 三个函数的区别在于 更详细的示例代码 交叉使用 内存泄漏 悬空指针 内存重叠 new 的语法 使用 new 运算符在堆上创建学生对象的示例 new和malloc都可以用于在堆上分配内存 calloc、realloc 和 malloc 是 C/C 中用于动态内存分配的函…

Mermaid使用教程(绘制各种图)

Mermaid使用教程&#xff08;绘制各种图&#xff09; 文章目录 Mermaid使用教程&#xff08;绘制各种图&#xff09;简介饼状图简单的例子应用案例 序列图简单案例应用案例另一个应用案例 甘特图简单案例应用案例一个更为复杂的应用案例 Git图简单案例 总结 简介 本文将主要介…

Elastic 8.12:AI Assistant for Observability 正式发布,更新至 Apache Lucene 9.9

作者&#xff1a;来自 Elastic Brian Bergholm 今天&#xff0c;我们很高兴地宣布 Elastic 8.12 全面上市。 有哪些新的功能&#xff1f; 8.12 版本的两个最重要的组成部分包括 Elastic AI Assistant for Observability 的 正式发布版 和 Apache Lucene 9.9 的更新&#xff08…

CVE2020-1938漏洞复现

这个漏洞是tomcat的 然后我们先了解漏洞产生的原理 首先我们先来看tmocat纠结是干什么的 tomcat是个中间件 最主要的两个结构、 servlet的定义和部分源码&#xff0c; 漏洞就是从这来的 tomcat处理http请求 源码分析 tomcat 8.5.46 哎 这教学视频讲半天看不懂 不看原…

RAG中的3个高级检索技巧

RAG系统检索的文档可能并不总是与用户的查询保持一致&#xff0c;这是一个常见的现象。当文档可能缺乏查询的完整答案或者包含冗余信息或包含不相关的细节&#xff0c;或者文档的顺序可能与用户的意图不一致时&#xff0c;就会经常出现这种情况。 本文将探讨三种有效的技术来增…

DC-5靶机做题记录

靶机下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1aZRB-hqvqLlGUmAPFljnIA?pwdelxg 提取码&#xff1a;elxg 参考&#xff1a; DC5官方地址&#xff1a;https://www.vulnhub.com/entry/dc-5,314/DC5靶机地址&#xff1a;https://download.vulnhub.com/d…

2024年17款最好用的免费录制网课软件分享

近年来&#xff0c;在线课程越来越受欢迎&#xff0c;为学习者提供了方便、灵活的教育内容获取方式。随着电子学习和网络培训的兴起&#xff0c;有许多工具可以帮助课程创建者记录和编辑其在线内容。虽然市场上有许多免费和付费工具&#xff0c;但本文将重点介绍 17 个用于录制…

前端学习路线图和一些经验

关于前端目前个人建议的一个路线,也是自己之前前端学习时候的一个大致路线,给想要学习前端的小白一个参考,以前自己刚开始接触前端的时候就是不知道该按照什么路线学习 eg-前端是做什么的&#xff1f; 就是开发网站,移动端&#xff0c;小程序之类的页面 调调接口完成页面的渲…

Ansible详解(架构,模块)及部署示例

Ansible概述 Ansible是一个基于Python开发的配置管理和应用部署工具&#xff0c;也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点&#xff0c;几乎可以实现Puppet和Saltstack能实现的功能。 Ansible是一款开源的IT自动化工具&#xff0c;它能够自动执行配置管理、…

如何免费从 SD 卡恢复已删除的文件?(照片、视频、MP3)

今天我们将告诉您如何免费从格式化的 SD 卡或闪存卡恢复文件。 特别是如果您是一名摄影师、博主或任何处理内容的人&#xff0c;您的 SD 卡上有一些内容&#xff0c;但您不小心删除或格式化了&#xff0c;现在您要向自己道歉。 无需担心&#xff0c;因为今天我们将告诉您如何…

vue写了debugger谷歌浏览器打开控制台没进断点

vue代码中打了断点&#xff0c;谷歌打开f12进不了断点解决方案如下 1、打开谷歌浏览器控制台&#xff0c;点击设置 2、在 Ignore List 中将“Enable Ignore Listing”勾选去掉&#xff0c;然后就可以正常使用debugger了

为了最大限度利用带宽,传输通道容量如何计算

一、结论&#xff1a; 传送通道容量 带宽 ✖️ 往返时延 二、过程&#xff1a; 1、传播时延和发送时延&#xff08;带宽&#xff09;通常决定一个报文的发送时间。 传输介质确定的时候&#xff0c;传播时延固定&#xff0c;发送时延根据数据报文的大小而不同。 ①传播时延…

GPT应用开发:编写插件获取实时天气信息

欢迎阅读本系列文章&#xff01;我将带你一起探索如何利用OpenAI API开发GPT应用。无论你是编程新手还是资深开发者&#xff0c;都能在这里获得灵感和收获。 本文&#xff0c;我们将继续展示聊天API中插件的使用方法&#xff0c;让你能够轻松驾驭这个强大的工具。 插件运行效…

elasticsearch6.6.0设置访问密码

elasticsearch6.6.0设置访问密码 第一步 x-pack-core-6.6.0.jar第二步 elasticsearch.yml第三步 设置密码 第一步 x-pack-core-6.6.0.jar 首先破解 x-pack-core-6.6.0.jar 破解的方式大家可以参考 https://codeantenna.com/a/YDks83ZHjd 中<5.破解x-pack> 这部分 , 也可…