Flask入门(10):Flask使用SQLAlchemy

news2024/12/24 11:44:54

目录

  • 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_engine

engine = 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 datetime


Base = 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 func

ret = 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博客

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

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

相关文章

浅析无人值守+智慧巡检变电站安全管控系统设计方案

一、项目背景 安全是电力生产的基石&#xff0c;确保电网安全和人身安全&#xff0c;是电网企业安全工作的出发点和落脚点。 随着智能信息化技术应用越来越广泛&#xff0c;智能信息化现场安全管理是近年来基于智能安全巡检技术下发展起来的现场作业安全管理新技术。 变电站运…

【机器学习】朴素贝叶斯算法

朴素贝叶斯&#xff08;Naive Bayes&#xff09;是经典的机器学习算法之一&#xff0c;也是为数不多的基于概率论的分类算法。由于朴素贝叶斯计算联合概率&#xff0c;所以朴素贝叶斯模型属于生成式模型。经典应用案例包括&#xff1a;文本分类、垃圾邮件过滤等。 1.贝叶斯公式…

rust 安装

rust 安装一、需要一个c的环境二、配置环境变量三、开始安装一、需要一个c的环境 安装Visual Studio 二、配置环境变量 Rust需要安装两个东西&#xff0c;一个是rustup&#xff0c;一个是cargo。所以你需要设置两个环境变量来分别指定他们的安装目录。 通过RUSTUP_HOME指定…

滤波算法:经典卡尔曼滤波

卡尔曼滤波实质上就是基于观测值以及估计值二者的数据对真实值进行估计的过程。预测步骤如图1所示&#xff1a; ​图1 卡尔曼滤波原理流程图 假设我们能够得到被测物体的位置和速度的测量值 ​&#xff0c;在已知上一时刻的最优估计值 ​以及它的协方差矩阵 的条件下&#xff…

ChatGPT热潮背后,金融行业大模型应用路在何方?——金融行业大模型应用探索

ChatGPT近两个月以来不断引爆热点&#xff0c;对人工智能应用发展的热潮前所未有地高涨&#xff0c;ChatGPT所代表的大模型在语义理解、多轮交互、内容生成中所展现的突出能力令人惊喜。而人工智能技术在金融行业的落地应用仍然面临挑战&#xff0c;虽然已经让大量宝贵的人力从…

易基因|ChIP-seq等组学研究鉴定出结直肠癌的致癌超级增强子:Nature子刊

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。超级增强子&#xff08;Super enhancer&#xff09;是一类包含多个普通增强子的大簇&#xff0c;主要富集高密度的转录因子、辅助因子及增强子相关表观修饰位点。与普通增强子相比&#xf…

canal实时同步mysql数据到elasticsearch(部署,配置,测试)

这里写目录标题简介工作原理MySQL主备复制原理canal 工作原理canal 使用流程环境搭建环境使用版本mysql配置修改配置创建从库权限账号创建测试数据库创建测试数据表elasticsearch配置创建索引建立映射canal的下载部署下载canal配置服务端 canal-deployer配置客户端canal-adapte…

Keysight E5061B网络分析仪

Keysight E5061B&#xff08;安捷伦&#xff09;网络分析仪可在 5 Hz 至 3 GHz 的宽频率范围内提供多功能的高性能网络分析。E5061B 提供了 ENA 系列共有的出色射频性能&#xff0c;还提供了成熟的 LF&#xff08;低频&#xff09;网络测量功能&#xff1b;包括带有内置 1 Mohm…

【Vue学习】Vue基本使用

1. 模板语法 插值&#xff1a;使用双大括号进行数据的插值&#xff0c;包括文本、JS表达式。动态属性&#xff1a;可以使用模板字符串。如果使用标签使用了v-html指令&#xff0c;那么标签中的子元素会被引入的html代码覆盖掉&#xff0c;同时也会存在xss风险。 2. compute…

Python + Airtest + poco + pytest + pytest-html 实现Android App自动化测试框架

Python Airtest poco pytest pytest-html 实现Android App自动化测试框架 一、背景 为了尝试除Appium外的测试框架&#xff0c;本文将介绍基于网易的airtest框架为基础&#xff0c;配合poco及pytest实现对Android App的自动化测试。 二、框架介绍 框架集成使用airtest p…

puzzle(1321)时间旅人

时间旅人 最强大脑同款项目。​​​​​​​ 每个指针会带动周围2圈指针一起带动&#xff0c;内圈8个旋转180度&#xff0c;外圈16个旋转90度&#xff0c;全部调整为朝上则胜利。 问题本质&#xff1a; 很明显&#xff0c;问题本质就是求每个格子的点击次数&#xff0c;最少为…

Mac mini 外接移动硬盘无法显示,磁盘工具装载报错显示 com apple diskmanagement disenter

使用“启动安全性实用工具”可确保 Mac 始终从您指定的启动磁盘以及合法的受信任操作系统启动。 如果您使用的是配备 Apple T2 安全芯片的 Mac&#xff0c;则“启动安全性实用工具”提供以下三项功能来帮助保护您的 Mac 免受未经授权的访问&#xff1a;固件密码保护、安全启动…

Java中安装Maven环境

Java中安装Maven环境 apache-maven-3.6.0 下载地址 云盘不限速下载 或者进入官网按下图下载 方法/步骤一 安装 打开压缩包&#xff0c;将maven压缩包解压至软件安装处&#xff0c;建议D根目录或其他&#xff0c;记住安装位置 类似于 方法/步骤二 环境变量配置 变量 1.新…

XSS-labs通关挑战

目录标题1、开始页面2、level 13、level 24、level 35、level 46、level 57、level 68、level 79、level 810、level 911、level 1012、level 1113、level 1214、level 131、开始页面 2、level 1 在url后面可以发现有注入点。如下&#xff1a; 这里出现弹窗&#xff0c;可以知道…

一文搞清楚LoRa网关,LoRa网关全知道

欢迎来到东用知识小课堂下面&#xff0c;今天我们用东用科技的OGC300系列LoRa为例&#xff0c;以简单的方式帮助大家了解一下LoRa相关的小知识一、LoRa网关的基本介绍LoRa是semtech公司创建的低功耗局域网无线标准&#xff0c;低功耗一般很难覆盖远距离&#xff0c;远距离一般功…

Roblox小游戏走出元宇宙试炼年

当元宇宙业务成为海内外互联网巨头急于甩掉的包袱时&#xff0c;“元宇宙第一股”Roblox最近的表现极其提气。 先是2月15日&#xff0c;这家在线游戏娱乐及创作平台公布上一年财报&#xff0c;公司全年营收为 22 亿美元&#xff0c;同比增长 16%。今年1 月&#xff0c;该公司的…

HIVE --- 高级查询

目录 CTE和嵌套查询 嵌套查询 关联查询&#xff08;join&#xff09; MapJoin MapJoin操作在Map端完成 开启MapJoin操作 MAPJOIN不支持的操作 union 数据交换&#xff08;import/export&#xff09; 数据排序 order by sort by distribute by cluster by CTE和嵌…

Authing 入选德勤“中国明日之星”企业榜单

近日&#xff0c;德勤发布“德勤中国明日之星”榜单&#xff0c;该项目致力于发掘和表彰蓬勃成长、持续创新、积极承担社会责任的卓越企业。该榜单1995 年创立至今&#xff0c;被业界誉为“全球高成长企业的标杆”。Authing 凭借在 IDaaS&#xff08;身份云&#xff09; 领域突…

【likeshop】开源商城系统代码有什么好?

​开源是什么&#xff1f; 开源是指软件的源代码开放给任何人自由使用、修改和再分发的概念。开源软件的源代码可以免费获取&#xff0c;用户可以根据自己的需要修改源代码&#xff0c;并且可以将修改后的代码免费分发给其他人使用。开源软件的源代码是公开的&#xff0c;其他人…

谈谈分布式系统的CAP理论

目录什么是CAP为什么三者不可得兼CAP原则权衡CAP原则实际应用什么是CAP CAP原则又称CAP定理&#xff0c;指的是在一个分布式系统中&#xff0c;Consistency&#xff08;一致性&#xff09;、 Availability&#xff08;可用性&#xff09;、Partition tolerance&#xff08;分区…