SqlAlchemy使用教程(五) ORM API 编程入门

在这里插入图片描述

  • SqlAlchemy使用教程(一) 原理与环境搭建
  • SqlAlchemy使用教程(二) 入门示例及编程步骤
  • SqlAlchemy使用教程(三) CoreAPI访问与操作数据库详解
  • SqlAlchemy使用教程(四) MetaData 与 SQL Express Language 的使用
  • SqlAlchemy使用教程(五) ORM API 编程入门

前一章用SQL表达式(SQL Express)语法操作数据库时,仍然侧重于从Core API的角度来看 SQL表达式语言,主要目的是通过封装的SQL表达式来实现跨不同数据库目的。

本章主要介绍ORM API 基础知识、实现ORM CRUD 基础操作。我尽可能使用简洁的语言,配合实例代码,帮助你尽快上手。下一章将深入学习ORM API的主要方法、使用方式,以及较复杂需求的编程实现。

1、ORM 原理

在第1章介绍过ORM原理时。 Python类对象通过ORM与数据库Table进行映射,通过Python类对象的方式来操作数据库。开发人员无须再使用各类数据库的接口API,以及SQL语法。
在这里插入图片描述

注: ORM的理想很丰满,现实却是这样的:用好ORM还是需要扎实的SQL基础才能用好。

ORM如何实现从Python对象到数据库的映射呢?

  1. 这种映射结构可分为如下几层
  2. Python Table类: 将 Database 的表结构 => 表示为 Python Metadata, 数据库字段 => Python Table类的属性(Column对象)
  3. Python Table 对象:数据的每行记录相当于1个Python类的实例对象(object),多行用 `object 列表` 表示。
  4. 数据库操作的ORM实现
    • 插入1行数据,就相当于: 新建1个Python类实例对象,通过ORM插入数据库
    • 通过ORM查询数据库,返回值为Python对象列表

2、ORM基础编程步骤

2.1 ORM API的使用步骤:

预备知识:

metadata:
上一章已详细介绍过,用于保存表结构, 通常1个应用定义1个全局metadata对象, 集中保存表结构。

declarative Table 声明式Table类
将数据库的表、字段,定义成Python类与属性的结构,这种结构称为声明式映射(Declarative Mapping)。Sqlalchemy2以后。table 类必须继承自 DeclarativeBase。

ORM API的使用流程:
(1)定义1个DeclarativeBase子类,做为Python table类的父类
(2)定义table类,映射到1个数据库表
(3)通过engine在数据库中实际创建表。 由Base.metadata向engine 发关create table DDL的事件.
(4)创建session对象,连接到engine,用于管理后续数据库操作。
(5)使用SQL Express Language语法的select, insert, update, delete等方法来执行数据库的增删改查操作。

说明:此处提到的 table 类,是为了描述方便,此类用于映射数据库表,不是上一节提到的sqlalchemy.Table 内置类。

2.2 声明式映射语法定义Table类与Column类

1)申明式定义table 类

继承自DeclarativeBase, column 字段定义遵照mapping 语法

定义1个Base做为Table类的基类

from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):pass

注:Base对象包含metadfata. registry 属性

Base.metadata
Base.registry

设置数据库表名
__tablename__ = "user_account" , 设置为db table 名

定义column属性,
name: Mapped[str] = mapped_column(String(30))
等号左边使用type notation注明Python类型,右边用mapped_column()给出最匹配的Database字段类型
这是SqlAlchemy2.0推荐的方式,别嫌麻烦,这样做可以大大减少数据库迁移时出错的概率,

下面是1个用声明式映射方式定义的Person 类。

from sqlalchemy.orm import DeclarativeBase, Session
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy import String, Integerclass Base(DeclarativeBase):passclass Person(Base):__tablename__ = 'person'id: Mapped[int] = mapped_column(primary_key=True)name: Mapped[str] = mapped_column(String(30))age: Mapped[int] = mapped_column(Integer)def __init__(self, name: str, age: int):self.name = nameself.age = agedef __repr__(self):return f"Person({self.name}, {self.age})"

说明:
上述模型类,除将用属性映射到数据库字段外,与普通类定义一样,也提供了对象初始化方法__init__(),以及__repr__()魔法方法。 还可以添加其它的方法,如属性的校验方法等。

2)通过engine对象在数据库中创建表

创建数据库连接引擎对象

engine = create_engine("mysql+mysqlconnector://root:12345678@localhost:3306/testdb")
# 请用你的mysql用户名及密码替换root:12345678

将DDL语句映射到数据库表,如果数据库表不存在,则创建该表

Base.metadata.create_all(engine)

2.3 向数据库插入数据

我们现在可以在数据库中插入数据了。通过创建类的实例来实现这一点. 还要使用一个名为Session的对象将它们传递到数据库,该对象利用Engine与数据库进行交互。使用Se木本油料Session.add(obj)添加1个对象(数据记录行),或使用Session.add_all()方法一次添加多个对象,而Session.commit()方法将用于保存对数据库的变更。

session = Session(engine)
# 创建Person实例对象
p1 = Person("刘备", 40)
p2 = Person("关羽", 38)
p3 = Person("张飞", 35)
# 将Person实例对象添加到session
session.add(p1)
session.add(p2)
session.add(p3)
session.commit()  # 提交事务到数据库

建议通过上下文管理器使用Session,即使用Python with语句。

2.4简单SELECT查询

对于数据库中的某些行,以下是发出SELECT语句以加载某些对象的最简单形式。要创建SELECT语句,
1)使用SELECT() 函数创建一个新的SELECT对象.
2) 使用Session调用该对象。在查询ORM对象时,通常有用的方法是Session.scalars()方法,它将返回一个ScalarResult对象,该对象将遍历我们选择的ORM对象:

stmt = select(Person).where(Person.name == "刘备")
results = session.scalars(stmt)
print(results.all())

Output:

[Person(刘备, 40)]

返回值 results对象为ScalarResult类实例,成员方法 all()以列表方式获取查询结果, 是1个对象列表,也很符合OOP的规范。

ScalarResult对象还提供了first(), fetchone(), fetchmany(), fetchall()等方法,习惯于DBAPI编程的同样都很熟悉。

ScalarResult对象也是可迭代的,用for 循环遍历读取结果

stmt = select(Person).where(Person.name.in_(["刘备", "关羽"]))
results = session.scalars(stmt)
for p in results:
print(p)

Output:

Person(刘备, 40)
Person(关羽, 38)

查询全部数据

results = session.scalars(select(Person).order_by(Person.age))

多条件查询

Where()方法不支持 and, or逻辑运算符,但支持where()方法的链式调用来实现多条件查询。

stmt = select(Person).where(Person.age > 35).where(Person.age < 50)
results = session.scalars(stmt)
print(results.all())

2.4 更新数据

更新数据时,先以对象的方式读取到1条数据后,更新该对象的属性,然后通过session提交事件,即自动将更新数据库相应记录。
例如。我们先在Person表中插入1条name=”张辽”的数据

p4 = Person("张辽", 36)
session.add(p4)
session.commit()  # 提交事务到数据库

然后获取该记录对象,将name属性改为”赵云”,提交更新。

stmt = select(Person).where(Person.name == "张辽")
person = session.scalars(stmt).first()
person.name = "赵云"
person.age = 32
session.commit()
results = session.scalars(select(Person).order_by(Person.age))
print(results.all())

Output

[Person(赵云, 32), Person(张飞, 35), Person(关羽, 38), Person(刘备, 40)]

2.5 删除数据

删除数据,也就是用session.delete()方法向engine传递1个对象。如果该对象不存在,则会抛出异常,如果该对象存在,则删除。

p5 = Person("曹操", 50)
try:session.delete(p5)
except Exception as e:print("数据库中不存在该记录")
p6 = session.scalars(select(Person).where(Person.name == "赵云")).first()
session.delete(p6)
session.commit()
results = session.scalars(select(Person).order_by(Person.age))
print(results.all())

Output:
数据库中不存在该记录

[Person(张飞, 35), Person(关羽, 38), Person(刘备, 40)]

3. 本章小结

ORM API编程的基本流程为:
1)用声明式映射方式,定义Python Table类,其父类必须是DeclarativeBase
2)Table类的属性映射到数据库字段,左边用 maped()注明Python类型,右边用mapped_column()申明对应的数据库字段类型。
3)用Base.metadata.emit()方法将DDL语句发送到数据库创建表。
4)创建Session对象,做为ORM 至 Database的管理器。
5)通过实例对象完成数据库的添加、修改、删除操作
6)通过select()查询数据, 并且提供了where(), order_by()等支持条件查询,排序等。

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

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

相关文章

用于垃圾回收的运行时配置选项

反馈 本文内容 指定配置的方法垃圾回收的风格管理资源使用情况大型页面 显示另外 4 个 此页面包含有关 .NET 运行时垃圾回收器 (GC) 设置的信息。 如果你要尝试让正在运行的应用达到最佳性能&#xff0c;请考虑使用这些设置。 然而&#xff0c;在特定情况下&#xff0c;默认…

基于大整形的运算收录

目录 目录 目录 前言 为什么要大整数 大整形的加/减法 大整形的乘法 大整形除法 大整形开方 代码实现 前言 好久没有更新博客了&#xff0c;hhh。时隔三个月&#xff0c;我又回来了。先来点简单的大整形&#xff0c;虽说简单&#xff0c;但是在编写的时候还是debug了…

学校门禁管理技巧,一招轻松学会!

随着社会的不断发展和科技的不断进步&#xff0c;安全管理成为各个领域至关重要的议题之一。门禁监控系统作为现代安全管理的关键组成部分&#xff0c;不仅为建筑物提供了有效的访问控制&#xff0c;还在提高整体安全性和管理效率方面发挥了关键作用。 客户案例 公司办公楼门禁…

php no input file specified

一、修改 .user.ini 文件 内容 open_basedir/wab/led-sportslight.com/:/tmp/ led-sportslight.com是项目根目录位置 改好后保存并清空缓存硬刷新网站就行了 二、mkdir(): Permission denied /core/library/think/cache/driver/File.php 第 84 行左右 mkdir(): Permission de…

2024最新最全【网络安全面试题含答案】(非常详细),零基础入门到精通

防范常见的 Web 攻击 什么是SQL注入攻击 攻击者在HTTP请求中注入恶意的SQL代码&#xff0c;服务器使用参数构建数据库SQL命令时&#xff0c;恶意SQL被一起构造&#xff0c;并在数据库中执行。 用户登录&#xff0c;输入用户名 lianggzone&#xff0c;密码 ‘ or ‘1’’1 &a…

使用 OpenCV 添加(混合)两个图像

目标 在本教程中&#xff0c;您将学习&#xff1a; 什么是线性混合以及为什么它有用;如何使用 addWeighted&#xff08;&#xff09; 添加两个图像 理论 注意 下面的解释属于Richard Szeliski的《计算机视觉&#xff1a;算法和应用》一书 从我们之前的教程中&#xff0c;…

LabVIEW扫描探针显微镜系统开发

在纳米技术对高精度材料特性测量的需求日益增长。介绍了基于LabVIEW开发的扫描探针显微镜&#xff08;SPM&#xff09;系统。该系统不仅可以高效地测量材料的热物性&#xff0c;还能在纳米尺度上探究热电性质&#xff0c;为材料研究提供了强大的工具。 系统基于扫描探针显微技…

(2)(2.1) Andruav Android Cellular(二)

文章目录 前言 5 Andruav Web Client 6 Andruav Telemetry 7 Andruav高级功能 8 将Andruav与SITL配合使用 9 FAQ 10 术语表 前言 Andruav 是一个基于安卓的互联系统&#xff0c;它将安卓手机作为公司计算机&#xff0c;为你的无人机和遥控车增添先进功能。 5 Andruav W…

数学建模--PageRank算法的Python实现

文章目录 1. P a g e R a n k PageRank PageRank算法背景2. P a g e R a n k PageRank PageRank算法基础2.1. P a g e R a n k PageRank PageRank问题描述2.2.有向图模型2.3.随机游走模型 3. P a g e R a n k PageRank PageRank算法定义3.1. P a g e R a n k PageRank PageRank…

GD32接收不定长数据包

接收不定长数据 Cubemx生成代码过程忽略 首先在main函数中创建接收缓存区 并在main.h中定义 接下来就是重写串口的中断函数中的内容&#xff0c;把原有内容注释掉 main中创建一个记录接收数据长度的变量和标志位 然后再在主函数中添加一个验证代码&#xff0c;这样MCU收到数据…

Cesium叠加超图二维服务、三维场景模型

前言 Cesium作为开源的库要加超图的服务则需要适配层去桥接超图与Cesium的数据格式。这个工作iClient系列已经做好&#xff0c;相比用过超图二维的道友们可以理解&#xff1a;要用Openlayer加载超图二维&#xff0c;那就用iClient for Openlayer库去加载&#xff1b;同样的要用…

Git与GitHub零基础教学

大家好&#xff0c;我是星恒&#xff0c;这个帖子给大家分享的是git和github的全套教程&#xff0c;包含github初始&#xff0c;git常用命令以及基本使用&#xff0c;git的ssh链接github&#xff0c;github使用token登录&#xff0c;github和idea的配合&#xff0c;一些平时常用…

Flink编程——基础环境搭建

基础环境搭建 文章目录 基础环境搭建准备环境搭建源码环境搭建克隆代码编译导入IDEA 集群环境搭建本地模式安装步骤 1&#xff1a;下载步骤 2&#xff1a;启动集群步骤 3&#xff1a;提交作业&#xff08;Job&#xff09;步骤 4&#xff1a;停止集群 总结 准备环境搭建 我们先…

web3d-three.js场景设计器-天空包围盒-TWEEN.js

THREE.JS 实现场景天空包围盒&#xff0c;为了让场景背景更具体&#xff0c;而不是呆板的纯色&#xff0c;可以给厂家添加围绕的包围盒。 这里使用球体来实现&#xff0c;球体中央则是场景给球体添加天空的渐变色加入场景 代码如下 function createSky( hemiLight) { const …

学习笔记——克里金插值

有一篇大神的文章写得非常的具体&#xff0c; https://xg1990.com/blog/archives/222 下面写下一些学习笔记&#xff1a; 1、关于克里金插值的基本原理 克里金插值来源于地理学&#xff0c;它的前提是地理学第一定律&#xff1a;所有事物都与其他事务相关&#xff0c;但是近…

应用层—HTTP详解(抓包工具、报文格式、构造http等……)

文章目录 HTTP1. 抓包工具的使用1.1 配置信息1.2 观察数据 2. 分析 https 抓包结果3. HTTP请求详解3.1 认识 URL3.1.1 URL 基本格式3.1.2 查询字符串 (query string)3.1.3 关于 URL Encode 3.2 认识 http 方法3.2.1 [经典问题] Get 和 Post 主要的区别是什么&#xff1f;&#…

Java多线程并发篇----第二十九篇

系列文章目录 文章目录 系列文章目录前言一、什么是不可变对象,它对写并发应用有什么帮助二、Java 中用到的线程调度算法是什么?三、什么是线程组,为什么在 Java 中不推荐使用?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点…

C++11手撕线程池 call_once 单例模式 Singleton / condition_variable 与其使用场景

一、call_once 单例模式 Singleton 大家可以先看这篇文章&#xff1a;https://zh.cppreference.com/w/cpp/thread/call_once /*std::call_oncevoid call_once( std::once_flag& flag, Callable&& f, Args&&... args ); */ #include <iostream> #i…

DT浏览器的人工智能是如何学习知识的

DT浏览器的人工智能是如何学习知识的&#xff0c;DT浏览器的人工智能通过大量的数据和算法来实现知识学习的。这是一些学习知识的方式&#xff1a; 1. 数据驱动学习&#xff1a;通过处理和分析大量的文本数据来学习语言知识和语言模式。这些数据可以来自各种来源&#xff0c;如…

解决 pnpm : 无法加载文件 C:\Program Files\nodejs\pnpm.ps1,因为在此系统上禁止运行脚本。

执行下面命令进行安装pnpm安装后 npm install -g pnpm 然后执行pnpm 报错 解决办法&#xff1a; 以管理员身份运行 Windows PowerShell &#xff0c; 在命令行输入以下命令后按回车&#xff0c; set-ExecutionPolicy RemoteSigned 再输入Y 回车即可。 再回到控制台输入p…