当前位置: 首页 > news >正文

Flask入门(10):Flask使用SQLAlchemy

目录

  • 11.SQLAlchemy
    • 11.1 简介
    • 11.2 安装
    • 11.3 基本使用
    • 11.4 连接
    • 11.5 数据类型
    • 11.6 执行原生sql
    • 11.7 插入数据
    • 11. 8 删改操作
    • 11.9 查询

11.SQLAlchemy

11.1 简介

SQLAlchemy的是Python的SQL工具包和对象关系映射,给应用程序开发者提供SQL的强大功能和灵活性。它提供了一套完整的企业级的持久性模式,专为高效率和高性能的数据库访问,改编成简单的Python的领域语言。
SQLAlchemy是Python界的ORM(Object Relational Mapper)框架,它两个主要的组件: SQLAlchemy ORM 和 SQLAlchemy Core 。

img

11.2 安装

pip install SQLAlchemy

11.3 基本使用

创建表

类使用声明式至少需要一个__tablename__属性定义数据库表名字,并至少一Column是主键

# SQLAlchemy练习
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String, UniqueConstraint, Index
from sqlalchemy.ext.declarative import declarative_base
# declarative_base类维持了一个从类到表的关系,通常一个应用使用一个base实例,所有实体类都应该继承此类对象Base = declarative_base()# 类使用声明式至少需要一个__tablename__属性定义数据库表名字,并至少一Column是主键
# 创建单表
class User(Base):__tablename__ = 'users'id = Column(Integer, primary_key=True, autoincrement=True)name = Column(String(32))extra = Column(String(16))def init_db():# 数据库链接引擎engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/flask01?charset=utf8", max_overflow=5)# 创建表Base.metadata.create_all(engine)def drop_db():engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/flask01?charset=utf8", max_overflow=5)# 删除表Base.metadata.drop_all(engine)if __name__ == "__main__":init_db()# drop_db()

插入数据

# SQLAlchemy练习
import models
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker# 数据库链接引擎
engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/flask01?charset=utf8", max_overflow=5)se = sessionmaker(bind=engine)
session = se()u1 = models.User(name='a1', extra='aa')
u2 = models.User(name='a2', extra='bb')session.add(u1)
session.add(u2)session.commit()
# session.rollback() # 回滚

session.rollback()表示回滚

11.4 连接

SQLAlchemy 把一个引擎的源表示为一个连同设定引擎选项的可选字符串参数的 URI。URI 的形式是:

dialect+driver://username:password@host:port/database

该字符串中的许多部分是可选的。如果没有指定驱动器,会选择默认的(确保在这种情况下 不 包含 + )。

Postgres:

postgresql://scott:tiger@localhost/mydatabase

MySQL:

mysql://scott:tiger@localhost/mydatabaseOracle:

oracle:

//scott:tiger@127.0.0.1:1521/sidname

SQLite (注意开头的四个斜线):

sqlite:absolute/path/to/foo.db

11.5 数据类型

这里写图片描述

SQLAlchemy列选项:

img

11.6 执行原生sql

from sqlalchemy import create_engineengine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/flask01?charset=utf8", max_overflow=5)# 执行SQL
cur = engine.execute("select * from users"
)# 获取第一行数据
re1 = cur.fetchone()
# 获取第n行数据
# re2 = cur.fetchmany(2)
# 获取所有数据
re3 = cur.fetchall()print(re3)
# 注意:当执行fetchone()后,数据已经被去除一条了,即使fetchall(),取出的数据也是从第二条数据开始的

engine.execute默认使用了数据库连接池,也可以使用DBUtils + pymysql做连接池

11.7 插入数据

创建如下表供后面增删改查使用。

models2.py

# sqlalchemy创建多个关联表
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String, UniqueConstraint, Index, DateTime, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
import datetimeBase = declarative_base()class Classes(Base):__tablename__ = 'classes'id = Column(Integer, primary_key=True, autoincrement=True)name = Column(String(32), nullable=False, unique=True)class Student(Base):__tablename__ = 'student'id = Column(Integer, primary_key=True, autoincrement=True)username = Column(String(32), nullable=False, unique=True)password = Column(String(32), nullable=False)ctime = Column(DateTime, default=datetime.datetime.now)  # 注意now后不要加()# 外键:对应的班级class_id = Column(Integer, ForeignKey('classes.id'))class Hobby(Base):__tablename__ = 'hobby'id = Column(Integer, primary_key=True, autoincrement=True)caption = Column(String(32), default='篮球')# 建立多对多的关系
class Student2Hobby(Base):__tablename__ = 'student2hobby'id = Column(Integer, primary_key=True, autoincrement=True)student_id = Column(Integer, ForeignKey('student.id'))hobby_id = Column(Integer, ForeignKey('hobby.id'))# 增加联合唯一索引__table_args__ = (UniqueConstraint('student_id', 'hobby_id', name='uni_student_id_hobby_id'),)def init_db():# 数据库链接引擎engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/flask01?charset=utf8", max_overflow=5)# 创建表Base.metadata.create_all(engine)def drop_db():engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/flask01?charset=utf8", max_overflow=5)# 删除表Base.metadata.drop_all(engine)if __name__ == "__main__":init_db()# drop_db()

上面创建完表后,开始执行插入操作:

# sqlalchemy的增删改查import models2
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker# 数据库链接引擎
engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/flask01?charset=utf8", max_overflow=5)se = sessionmaker(bind=engine)
session = se()# 单条增加
# c1 = models2.Classes(name='python入门')
# session.add(c1)
# session.commit()
# session.close()# 多条增加
# c2 = [
#     models2.Classes(name='python进阶'),
#     models2.Classes(name='python高级'),
#     models2.Classes(name='python web')
# ]
# session.add_all(c2)
# session.commit()
# session.close()

11. 8 删改操作

# sqlalchemy的增删改查import models2
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker# 数据库链接引擎
engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/flask01?charset=utf8", max_overflow=5)se = sessionmaker(bind=engine)
session = se()# 删除
# session.query(models2.Classes).filter(models2.Classes.id > 2).delete()
# session.commit()# 修改
# session.query(models2.Classes).filter(models2.Classes.id > 2).update({"name" : "099"})
session.query(models2.Classes).filter(models2.Classes.id > 2).update({models2.Classes.name: models2.Classes.name + "099"}, synchronize_session=False)
synchronize_session = False  # 对字段执行字符串操作
# session.query(models2.Classes).filter(models2.Classes.id > 2).update({"num": models2.Classes.num + 1}, synchronize_session="evaluate")
# synchronize_session = 'evaluate'  # 对字段执行数值型操作
session.commit()

11.9 查询

参考:Flask-SQLAlchemy - 武沛齐 - 博客园 (cnblogs.com)

1.以下的方法都是返回一个新的查询,需要配合执行器使用。

filter(): 过滤,功能比较强大,多表关联查询。
filter_by():过滤,一般用在单表查询的过滤场景。

order_by():排序。默认是升序,降序需要导包:from sqlalchemy import * 。然后引入desc方法。比如order_by(desc(“email”)).按照邮箱字母的降序排序。

group_by():分组。

2.以下都是一些常用的执行器:配合上面的过滤器使用。

get():获得id等于几的函数。

比如:查询id=1的对象。

get(1),切记:括号里没有“id=”,直接传入id的数值就ok。因为该函数的功能就是查询主键等于几的对象。

all():查询所有的数据。

first():查询第一个数据。

count():返回查询结果的数量。

paginate():分页查询,返回一个分页对象。

paginate(参数1,参数2,参数3)=>参数1:当前是第几页;参数2:每页显示几条记录;参数3:是否要返回错误。

返回的分页对象有三个属性:items:获得查询的结果,pages:获得一共有多少页,page:获得当前页。

3.常用的逻辑符:

需要导入包才能用的有:from sqlalchemy import *

not_、and_、or_ 还有上面说的排序desc。

常用的内置的有:in_:表示某个字段在什么范围之中。

4.其他关系的一些数据库查询:

endswith():以什么结尾。

startswith():以什么开头。

contains():包含

# sqlalchemy的增删改查import models2
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql import text# 数据库链接引擎
engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/flask01?charset=utf8", max_overflow=5)se = sessionmaker(bind=engine)
session = se()# 查询r1 = session.query(models2.Classes).all()  # 返回models2.Classes对象# label相当于sql里的as,取别名,后面结果集使用也是使用别名
r2 = session.query(models2.Classes.name.label('xx'), models2.Classes.name).all()# 查询课程名字为python入门的课程
r3 = session.query(models2.Classes).filter(models2.Classes.name == "python入门").all()
# 也可使用filter_by,注意filter_by的传参和filter不一样
r4 = session.query(models2.Classes).filter_by(name='python入门').all()# 查询课程名字为python入门的课程的第一个
r5 = session.query(models2.Classes).filter_by(name='python入门').first()# 查询id<2且课程名字为python入门的课程
r6 = session.query(models2.Classes).filter(text("id<:value and name=:name")).params(value=2, name='python入门').order_by(models2.Classes.id).all()# from_statement相当于子查询
r7 = session.query(models2.Classes).from_statement(text("SELECT * FROM Classes where name=:name")).params(name='python入门').all()print(r7)
session.close()
# 注意:除了r2,其他结果都为models2.Classes对象
# 条件
ret = session.query(Users).filter_by(name='alex').all()
ret = session.query(Users).filter(Users.id > 1, Users.name == 'eric').all()
ret = session.query(Users).filter(Users.id.between(1, 3), Users.name == 'eric').all()
ret = session.query(Users).filter(Users.id.in_([1,3,4])).all()
ret = session.query(Users).filter(~Users.id.in_([1,3,4])).all()
ret = session.query(Users).filter(Users.id.in_(session.query(Users.id).filter_by(name='eric'))).all()
from sqlalchemy import and_, or_
ret = session.query(Users).filter(and_(Users.id > 3, Users.name == 'eric')).all()
ret = session.query(Users).filter(or_(Users.id < 2, Users.name == 'eric')).all()
ret = session.query(Users).filter(or_(Users.id < 2,and_(Users.name == 'eric', Users.id > 3),Users.extra != "")).all()# 通配符
ret = session.query(Users).filter(Users.name.like('e%')).all()
ret = session.query(Users).filter(~Users.name.like('e%')).all()# 限制
ret = session.query(Users)[1:2]# 排序
ret = session.query(Users).order_by(Users.name.desc()).all()
ret = session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all()# 分组
from sqlalchemy.sql import funcret = session.query(Users).group_by(Users.extra).all()
ret = session.query(func.max(Users.id),func.sum(Users.id),func.min(Users.id)).group_by(Users.name).all()ret = session.query(func.max(Users.id),func.sum(Users.id),func.min(Users.id)).group_by(Users.name).having(func.min(Users.id) >2).all()# 连表ret = session.query(Users, Favor).filter(Users.id == Favor.nid).all()
# 默认使用外键进行连表
ret = session.query(Person).join(Favor).all()  # 内连接ret = session.query(Person).join(Favor, isouter=True).all() # 左连接# 组合
q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union(q2).all()q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union_all(q2).all()

参考:
https://blog.csdn.net/u011146423/article/details/87605812

​ Python开发【第十九篇】:Python操作MySQL - 武沛齐 - 博客园 (cnblogs.com)

​ SQLAlchemy 学习笔记_JP.Zhang-CSDN博客

相关文章:

Flask入门(10):Flask使用SQLAlchemy

目录11.SQLAlchemy11.1 简介11.2 安装11.3 基本使用11.4 连接11.5 数据类型11.6 执行原生sql11.7 插入数据11. 8 删改操作11.9 查询11.SQLAlchemy 11.1 简介 SQLAlchemy的是Python的SQL工具包和对象关系映射&#xff0c;给应用程序开发者提供SQL的强大功能和灵活性。它提供了…...

我的 System Verilog 学习记录(4)

引言 本文简单介绍 System Verilog 语言的 数据类型。 前文链接&#xff1a; 我的 System Verilog 学习记录&#xff08;1&#xff09; 我的 System Verilog 学习记录&#xff08;2&#xff09; 我的 System Verilog 学习记录&#xff08;3&#xff09; 数据类型简介 Sys…...

Git : 本地分支与远程分支的映射关系

概述 本文介绍 git 环境中本地分支与远程分支的映射关系的查看和调整。 1、查看本地分支与远程分支的映射关系 执行如下命令&#xff1a; git branch -vv注意就是两个 v &#xff0c;没有写错。 可以获得分支映射结果&#xff1a; dev fa***** [github/dev] update * main…...

运维必看|跨国公司几千员工稳定访问Office365,怎么实现?

【客户背景】本次分享的客户是全球传感器领域的领导者&#xff0c;其核心产品为电流和电压传感器&#xff0c;被广泛应用于驱动和焊接、可再利用能源以及电源、牵引、高精度、传统和新能源汽车等领域。 作为一家中等规模的全球化公司&#xff0c;该公司在北京、日本、西欧、东欧…...

Python GDAL读取栅格数据并基于质量评估波段QA对指定数据加以筛选掩膜

本文介绍基于Python语言中gdal模块&#xff0c;对遥感影像数据进行栅格读取与计算&#xff0c;同时基于QA波段对像元加以筛选、掩膜的操作。本文所要实现的需求具体为&#xff1a;现有自行计算的全球叶面积指数&#xff08;LAI&#xff09;.tif格式栅格产品&#xff08;下称“自…...

Vue3:有关v-model的用法

目录 前言&#xff1a; 回忆基本的原生用法&#xff1a; 原生input的封装&#xff1a; 自定义v-model参数&#xff1a; 对el-input的二次封装&#xff1a; 多个v-model进行绑定: v-model修饰符&#xff1a; v-model自定义参数与自定义修饰符的结合&#xff1a; 前言&am…...

CF1692C Where‘s the Bishop? 题解

CF1692C Wheres the Bishop? 题解题目链接字面描述题面翻译题目描述题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1提示代码实现题目 链接 https://www.luogu.com.cn/problem/CF1692C 字面描述 题面翻译 题目描述 有一个888\times888的棋盘&#xff0c;列编号从…...

Jenkins集成Allure报告

Jenkins集成Allure报告 紧接上文&#xff1a;Jenkins部署及持续集成——傻瓜式教程 使用Allure报告 1、在插件库下载Allure插件Allure Jenkins Plugin 2、在构建后操作中加入allure执行的报告目录&#xff08;相对于项目的路径&#xff09; 3、run.py代码改成如下 import p…...

【数据结构】AVL树

AVL树一、AVL树的概念二、AVL的接口2.1 插入2.2 旋转2.2.1 左单旋2.2.2 右单旋2.2.3 左右双旋2.2.4 右左双旋三、验证四、源码一、AVL树的概念 当我们用普通的搜索树插入数据的时候&#xff0c;如果插入的数据是有序的&#xff0c;那么就退化成了一个链表&#xff0c;搜索效率…...

这一次我不再低调,老板法拉利的车牌有我的汗水

起源: 5Why分析法最初是由丰田佐吉提出的,后来,丰田汽车公司在发展完善其制造方法学的过程中持续采用该方法。5Why分析法作为丰田生产系统的入门课程之一,是问题求解的关键培训课程。丰田生产系统的设计师大野耐一曾将5Why分析法描述为:“丰田科学方法的基础,重复五次,问…...

通过连接另一个数组的子数组得到一个数组

给你一个长度为 n 的二维整数数组 groups &#xff0c;同时给你一个整数数组 nums 。 你是否可以从 nums 中选出 n 个 不相交 的子数组&#xff0c;使得第 i 个子数组与 groups[i] &#xff08;下标从 0 开始&#xff09;完全相同&#xff0c;且如果 i > 0 &#xff0c;那么…...

公派访问学者的申请条件

知识人网海外访问学者申请老师为大家分享公派访问学者申请的基本条件以及哪些人员的申请是暂不受理的&#xff0c;供大家参考&#xff1a;一、 申请人基本条件&#xff1a;1.热爱社会主义祖国&#xff0c;具有良好的思想品德和政治素质&#xff0c;无违法违纪记录。2.具有良好专…...

多点电容触摸屏实验

目录 一、简介 二、硬件原理 ​编辑1、CT_INT 2、I2C2_SCL和I2C2_SDA 3、RESET复位引脚 三、FT54x6/FT52x6电容触摸芯片 四、代码编写 1、编写ft5426.h 2、编写ft5426.c 3、main函数 一、简介 电容屏只需要手指轻触即可&#xff0c;而电阻屏是需要手指给予一定的压力才…...

【算法与数据结构(C语言)】栈和队列

文章目录 目录 前言 一、栈 1.栈的概念及结构 2.栈的实现 入栈 出栈 获取栈顶元素 获取栈中有效元素个数 检测栈是否为空&#xff0c;如果为空返回非零结果&#xff0c;如果不为空返回0 销毁栈 二、队列 1.队列的概念及结构 2.队列的实现 初始化队列 队尾入队列 队头出队列 获…...

Uni-app使用vant和uview组件

目录 1.安装vant组件 1.1安装前需知 1.2.安装 1.3.创建uni-app项目 2.安装uview-ui组件 2.1官网 2.2安装 2.3安装成功 1.安装vant组件 1.1安装前需知 小程序能使用vant-weapp组件&#xff0c;且官网的安装是直接导入小程序中&#xff0c;不能直接导入uni-app框架中 V…...

2023年PMP考试应该注意些什么?

首先注意&#xff08;报考条件&#xff09; 2023年PMP考试报名流程&#xff1a; 一、PMP英文报名&#xff1a; 英文报名时间无限制&#xff0c;随时可以报名&#xff0c;但有一年的有效期&#xff0c;所以大家尽量提前报名&#xff0c;在英文报名有效期内进行中文报名。 英…...

selenium环境安装及使用

selenium简介官网https://www.selenium.dev简介用于web浏览器测试的工具支持的浏览器包括IE&#xff0c;Firefox,Chrome&#xff0c;edge等使用简单&#xff0c;可使用java&#xff0c;python等多种语言编写用例脚本主要由三个工具构成&#xff0c;webdriver,IDE,web自动化环境…...

高性能低功耗4口高速USB2.0 HUB 完美替代FE1.1S和FE8.1

该NS1.1s是一个高度集成的&#xff0c;高品质&#xff0c;高性能&#xff0c;低功耗&#xff0c;为USB 2.0高速4端口集线器又低成本的解决方案。 &#xff08;点击即可咨询芯片详细信息&#xff09; NS1.1s的特点 1.通用串行总线规范修订版2.0&#xff08;USB 2.0&#xff09;完…...

Go全栈学习(一)基础语法

Go语言基础语法 文章目录Go语言基础语法注释变量变量的定义变量的交换理解变量&#xff08;内存地址&#xff09;匿名变量变量的作用域常量2023.2.4日 总结// 关于Goland 中 执行的问题// 1、包下执行 &#xff08;一个 main 函数来执行&#xff0c;如果有多个&#xff0c;无法…...

centos7搭建svn配置

基本概述 Apache Subversion&#xff08;简称SVN&#xff0c;svn&#xff09;&#xff0c;一个开放源代码的版本控制系统&#xff0c;相较于RCS、CVS&#xff0c;它采用了分支管理系统&#xff0c;它的设计目标就是取代CVS。互联网上很多版本控制服务已从CVS转移到Subversion。…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...