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类及类属性,
  3. Python Table对象:表的每行记录相当于1个Python类的实例对象
  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子类,做为所有Table类的父类
(2)定义Table类,映射到1个数据库表
(3)通过engine在数据库中实际创建表。 由Base.metadata向engine 发关create table DDL的事件.
(4)创建session对象,连接到engine,用于管理后续数据库操作。
(5)使用SQL Express Language语法的select, insert, update, delete等方法来执行数据库的增删改查操作。

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.rhkb.cn/news/241055.html

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

相关文章

在js文件中引入外部变量

需求背景: 有个ip地址需要在项目部署后修改为客户自己的,所以就把这个ip放到了外部进行管理,方便直接修改 实现方法: 第一步:在public文件夹下创建一个json文件,里面放的就是需要在外部进行管理,随时都可以修改的变量 第二步:在需要引变量的js文件中写入如下代码 结合第一步…

2017年认证杯SPSSPRO杯数学建模A题(第一阶段)安全的后视镜全过程文档及程序

2017年认证杯SPSSPRO杯数学建模 A题 安全的后视镜 原题再现&#xff1a; 汽车后视镜的视野对行车安全非常重要。一般来说&#xff0c;汽车的后视镜需要有良好的视野范围&#xff0c;以便驾驶员能够全面地了解车后方的道路情况。同时&#xff0c;后视镜也要使图像的畸变尽可能…

一款 StarRocks 客户端工具,支持可视化建表、数据编辑

什么是 StarRocks&#xff1f; StarRocks 是新一代极速全场景 MPP (Massively Parallel Processing) 数据库。StarRocks 的愿景是能够让用户的数据分析变得更加简单和敏捷。用户无需经过复杂的预处理&#xff0c;就可以用 StarRocks 来支持多种数据分析场景的极速分析。 为了…

IDEA中启动项目报堆内存溢出或者没有足够内存的错误

1.报错现象 java.lang.OutOfMemoryError: Java heap space 或者 Could not reserve enough space for object heap 2.解决办法 在运行配置中VM选项后加下面的配置&#xff1a; -server -XX:MaxHeapSize256m -Xms512m -Xmx512m -XX:PermSize128M -XX:MaxPermSize256m 3.JVM虚…

Cloudflare cdn 基本使用

个人版免费试用&#xff0c;一个邮箱账号只能缓存一个网站cdn。 地址&#xff1a;cloudflare.com 创建站点 在网站创建站点&#xff0c;填上你的域名 点击进入网站 缓存全局配置 可清除缓存&#xff0c;设置浏览器缓存时间 我设置了always online,防止服务器经常不稳定 缓…

RK3568平台开发系列讲解(Linux系统篇)设备树中 GPIO 相关属性

🚀返回专栏总目录 文章目录 一、RK ft5x06 设备树节点二、gpio-controller三、#gpio-cells四、gpio-ranges五、gpio 引脚描述属性沉淀、分享、成长,让自己和他人都能有所收获!😄 一、RK ft5x06 设备树节点 我们以ft5x06设备树中的gpio使用为例: 二、gpio-controller

Vue学习笔记9--vuex(专门在Vue中实现集中式状态(数据)管理的一个Vue插件)

一、vuex是什么&#xff1f; 概念&#xff1a;专门在Vue中实现集中式状态&#xff08;数据&#xff09;管理的一个Vue插件&#xff0c;对vue应用中多个组件的共享状态进行集中式的管理&#xff08;读/写&#xff09;&#xff0c;也是一种组件间通信的方式&#xff0c;且适用于…

人工智能 AI 如何让我们的生活更加便利

每个人都可以从新技术中获益&#xff0c;一想到工作或生活更为便利、简捷且拥有更多空余时间&#xff0c;谁会不为之高兴呢&#xff1f;借助人工智能&#xff0c;每天能够多一些空余时间&#xff0c;或丰富自己的业余生活&#xff0c;为培养日常兴趣爱好增添一点便利。从电子阅…

【Docker】网络模式详解及容器间网络通信

目录 一、概述 二、默认网络 三、网络模式及应用 1. Bridge模式 2. Host模式 3. none网络模式 四、自定义网络应用 1. 网络相连 2. 自定义通讯 3. 自定义IP 每篇一获 一、概述 在 Docker 中&#xff0c;网络设置包括 IP 地址、子网掩码、网关、DNS 和端口号等关键组…

一文了解GeoTrust SSL证书

在当今互联网的高度连接世界中&#xff0c;确保网站安全性至关重要。SSL证书是保护网站和用户数据的关键组成部分。GeoTrust证书在SSL证书市场上享有盛誉&#xff0c;被许多网站所有者和企业所信赖。JoySSL将深入探讨GeoTrust证书的特点&#xff0c;帮助大家了解该品牌并做出更…

Go后端开发 -- 反射reflect 结构体标签

Go后端开发 – 反射reflect && 结构体标签 文章目录 Go后端开发 -- 反射reflect && 结构体标签一、反射reflect1.编程语言中反射的概念2.interface 和反射3.变量内置的pair结构4.reflect的基本功能TypeOf和ValueOf5.从relfect.Value中获取接口interface的信息6…

Docker本地私有仓库搭建配置指导

一、说明 因内网主机需要拉取镜像进行Docker应用&#xff0c;因此需要一台带外主机作为内网私有仓库来提供内外其他docker业务主机使用。参考架构如下&#xff1a; 相关资源&#xff1a;加密、Distribution registry、Create and Configure Docker Registry、Registry部署、D…

【C语言深度剖析——第三节(关键字3)】《C语言深度解剖》+蛋哥分析+个人理解

本文由睡觉待开机原创&#xff0c;未经允许不得转载。 本内容在csdn网站首发 欢迎各位点赞—评论—收藏 如果存在不足之处请评论留言&#xff0c;共同进步&#xff01; 目录 1.基本数据类型2.sizeof关键字 前言&#xff1a; 本期我们继续探讨关于C深度解剖这本书相关内容&#…

Java爬虫爬取图片壁纸

Java爬虫 以sougou图片为例&#xff1a;https://pic.sogou.com/ JDK17、SpringBoot3.2.X、hutool5.8.24实现Java爬虫&#xff0c;爬取页面图片 项目介绍 开发工具&#xff1a;IDEA2023.2.5 JDK&#xff1a;Java17 SpringBoot&#xff1a;3.2.x 通过 SpringBoot 快速构建开发环境…

IT大侦“碳”:Concept Luna向循环设计持续演进

IT大侦“碳”&#xff1a;Concept Luna向循环设计持续演进

代码、课程、教学的一些思考-2024

1 代码、算法、艺术品 1.1 代码 最典型的C代码示例。 以下是一个简单的C代码示例&#xff0c;它打印出“Hello, World!”&#xff1a; #include <iostream> int main() { std::cout << "Hello, World!"; return 0; } 这段代码定义了一个程序&a…

C#winform上位机开发学习笔记1-串口助手的ModbusCRC功能

1.首先自定义CRC校验函数 private UInt16 Crc_Check(byte[] Data, byte DataLEN){UInt16 CRC 0xFFFF;for (byte i 0; i < DataLEN; i){ CRC ^ Data[i];for(byte j 0; j < 8; j){if((CRC & 0x0001) 0x0001){CRC (UInt16)((CRC >> 1) ^ 0xA001);}else{CRC …

DDoS攻击规模最大的一次

有史以来DDoS攻击规模最大的是哪一次&#xff1f; Google Cloud团队在2017年9月披露了一次此前未公开的DDoS攻击&#xff0c;其流量达 2.54Tbps&#xff0c;是迄今为止有记录以来最大的DDoS攻击。 在同时发布的另一份报告中&#xff0c;分析高端威胁团体的谷歌安全团队谷歌威胁…

Vray渲染效果图材质参数设置

渲染是创造出引人入胜视觉效果的关键步骤&#xff0c;在视觉艺术领域尤为重要。不过&#xff0c;渲染作为一个资源密集型的过程&#xff0c;每当面对它时&#xff0c;我们往往都会遭遇到时间消耗和资源利用的巨大挑战。幸运的是&#xff0c;有几种方法能够帮助我们优化渲染&…

网易云音乐 API

网易云音乐 API 网易云音乐 API灵感来自环境要求安装运行Vercel 部署操作方法 可以在Node.js调用支持 TypeScript使用文档功能特性更新日志单元测试SDK贡献者License 网易云音乐 API 网易云音乐 Node.js API service 灵感来自 disoul/electron-cloud-music darknessomi/musi…