flask-sqlalchemy库

news2025/2/26 17:58:19

彩笔激流勇退。

1. 简介

ORM,对象关系映射。简单来说,ORM将数据库中的表与面向对象中的类建立了一种对应关系。这样,我们要操作数据库,表,记录就可以直接通过操作类或者类实例来完成。

SQLAlchemy 是目前python中最垃圾的 ORM框架, 功能全面, 使用复杂。

Flask-SQLAlchemy 是一个为 Flask 应用增加 SQLAlchemy 支持的扩展,把原本pymysql几句话就能搞定的事情整成抽象的,继承的,封装的,多态的更适合高级程序员体质的负离子保温杯。

抛开兼容性不谈,Flask-SQLAlchemy无疑是磨练程序员改bug的磨刀石,是检验程序员记忆能力的试金石,是凝结了人类精华的草酸钙结石。

常用字段类型

类型名python接收类型mysql生成类型说明
Integerintint整型
Floatfloatfloat浮点型
Numeric(5,2)decimal.Decimaldecimal(5,2)
Booleanbooltinyint整型,只占1个字节
Textstrtext文本类型,最大64KB
LongTextstrlongtext文本类型,最大4GB
Stringstrvarchar变长字符串,必须限定长度
Datedatetime.datedate日期
DateTimedatetime.datetimedatetime日期和时间
Timedatetime.timetime时间
TIMESTAMPdatetime.datetimeTIMESTAMP时间戳,可以用text(‘now()’)赋值

常用的字段选项

选项名说明
primary_keyTrue,则该字段为表的主键,默认自增
uniqueTrue,则这列设置唯一
nullableFalse,则这列设置非空
default为这列设置默认值,不作用在数据库
server_default值必须是字符串格式,作用在数据库
indexTrue,则为这列创建索引,提高查询效率

如果没有给对应字段的类属性设置default参数, 且添加数据时也没有给该字段赋值, 则sqlalchemy会给该字段设置默认值 None。

常见命令

db.create_all() #创建所有表
db.drop_all() #删除所有表
2. 创建表

pip install pymysql

pip install flask-sqlalchemy

数据库URL(连接地址)格式: 协议名://用户名:密码@数据库IP:端口号/数据库名

main.py

​ 在下面代码中,我们使用了 with app.app_context(): 语句来确保当前应用实例的操作db.create_all() 是在flask应用上下文中被调用的。

from app import *
from models import User

@app.route('/',methods=['GET','POST'])
def login():
    print(db)
    return 'hello world'

if __name__ == '__main__':
    with app.app_context():
        db.create_all()#创建表
    app.run(host='0.0.0.0',port=9901,debug=1)

modules.py

表名默认为类名小写, 可以通过 __tablename__类属性 进行修改

from app import db

class User(db.Model):# User表
    __tablename__ = 't_user'
    id= db.Column(db.Integer,primary_key=True) # 必须要有主键存在
    name=db.Column(db.String(20),nullable=True)# 可空
    age=db.Column(db.SmallInteger)
    gender=db.Column(db.Boolean)
    birthday=db.Column(db.Date)

对应MySQL语句

CREATE TABLE `t_user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(20) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `age` smallint DEFAULT NULL,
  `gender` tinyint(1) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

app.py

from flask import Flask,url_for,request,render_template,make_response,redirect,jsonify
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__) # 用本脚本名实例化Flask对象
# 设置数据库连接地址
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@127.0.0.1:3306/test1'

# 是否追踪数据库修改(开启后会触发一些钩子函数)  一般不开启, 会影响性能
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 是否显示底层执行的SQL语句
app.config['SQLALCHEMY_ECHO'] = True

# 初始化组件对象, 直接关联Flask应用
db = SQLAlchemy(app)
3. 数据表简单查询

在这里插入图片描述

user=User.query

说明
user.filter_by(id=1)只能等值查询,使用=
user.filter(User.id==1)条件查询,用==
use.filter 参数与运算符说明
and_(User.id==1,User.age==99)
or_(User.id==1,User.age==99)
~(User.id==1)
!= None>>=
User.name.like('%a%')模糊查询
User.id.in_((1,2,5))范围查询
User.id.between(1,3)[1,3]
if __name__ == '__main__':
    with app.app_context():
        db.create_all()
        user=User.query
        print(user)#显示sql语句, 返回Query对象
        print(user.all())#[<User 1>, <User 2>, <User 3>],每个元素都是models.User类型
        print(user.count()) #返回query中的Model对象数量
        print(user.filter_by(age=30,id=1)) #显示SQL语句, 返回Query对象,内部条件为交集
4. 映射查询 db.session.query

映射查询在SQLAlchemy中,可以通过session对象的query方法完成。

注意关键字书写顺序

db.session.query().filter().group_by().having().order_by().paginate().all()
if __name__ == '__main__':
    with app.app_context():
        db.create_all()
        query=db.session.query(User) #<class 'flask_sqlalchemy.query.Query'>
        print(query.filter(User.id>1).all())# [<User 2>, <User 3>]
        query2=db.session.query(User.id,User.name)
        print(query2.filter(User.age==99).all())# [(2, 'tom')]
    app.run(host='0.0.0.0',port=9901,debug=1)
5. 排序 order_by

from sqlalchemy import desc

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
        query = db.session.query(User.id, User.name,User.age)
        print(query.order_by(User.age).all())  # 默认升序排序,asc()
        print(query.order_by(desc(User.age)).all())  # 降序排序
        print(query.order_by(User.age,User.id).all())  # 先排age,后排id
    app.run(host='0.0.0.0', port=9901, debug=1)# 看起来是一个阻塞函数
6. 聚合函数

数据库先添加一个age为30的记录。

from sqlalchemy import func

聚合函数说明
count()记录数量
sum()加和总值
avg()平均值
max()最大值
min()最小值
if __name__ == '__main__':
    with app.app_context():
        db.create_all()
        query = db.session.query(func.max(User.age),func.avg(User.age))
            #相当于 SELECT max(age) , avg(age) FROM t_user
        print(query.all())  # [(99, Decimal('51.0000'))]
    app.run(host='0.0.0.0', port=9901, debug=1)
7. 分组查询 group_by
if __name__ == '__main__':
    with app.app_context():
        db.create_all()
        query = db.session.query(func.count(User.id))
        print(query.group_by(User.age).all())  
        # [(2,), (1,), (1,)]
    app.run(host='0.0.0.0', port=9901, debug=1)
8. 增删改

flask开了debug模式,删除数据会导致main函数重新执行,给爷整笑了。

if __name__ == '__main__':
    with app.app_context():
        db.create_all()

        #更新
        u = db.session.query(User.id==1)# 查询主键为1的记录
        u.name="Jack"
        #db.session.rollback() 事务回滚,默认遇到错误自动回滚
        db.session.commit()# 事务提交

        #删除
        u2=db.session.query(User).filter(User.id==6).all() # User 模型的实例
        if len(u2)!=0:
            db.session.delete(u2[0])
            db.session.commit()  # 事务提交

        #增加
        u3=User(id=7,name="lihua",age=35,gender=1,birthday='2077-1-1')
        db.session.add(u3)
        #db.session.add_all([u1,u2,u3]) 一次添加多个
        db.session.commit()

    app.run(host='0.0.0.0', port=9901, debug=0)
    # debug=1时,上面的delete操作会执行多次
    # 大概是是检测到了文件变化重启了一次main函数???
9. 分页查询 paginate

分页查询不老老实实用limit,非要整个paginate装什么高大上。

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
        pg=db.session.query(User).paginate(page=2,per_page=2)# QueryPagination object
        print(pg.items)#[<User 3>, <User 4>],当前页数据
        print(pg.pages) #3 ,一共三页
        for i in pg.iter_pages(): #迭代Pagination.iter_pages对象
            print(i)#1 2 3
    app.run(host='0.0.0.0', port=9901, debug=0)
10. 原生sql支持
if __name__ == '__main__':
    with app.app_context():
        db.create_all()
        statement=text('select * from t_user where id> :id').params(id=1)
        query=db.session.query(User).from_statement(statement)
        print(query.all())# [<User 2>, <User 3>, <User 4>, <User 7>]

        #最傻逼的地方来了,新版本下面语句不支持
        # statement2 = text('select max(id) as mmid,max(age) as mage from t_user where id> :id').params(id=2)
        # query2 = db.session.query('mmid','mage').from_statement(statement2)# sqlalchemy.exc.ArgumentError

        # 感觉不如直接pymysql
        sql=text('select max(id) as mmid,max(age) as mage from t_user where id> :id')
        result=db.session.execute(sql,{'id':2})# CursorResult object
        #print(result.fetchall())# [(7, 45)] 如果这里获取了,下面就获取不了,有点类似游标后移导致没数据读
        for i in result:
            print(i)# (7, 45)
    app.run(host='0.0.0.0', port=9901, debug=0)

参考

flask框架与mysql开发入门到实践 白菜爱科技

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

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

相关文章

连接时序分类 Connectionist Temporal Classification (CTC)

CTC全称Connectionist temporal classification&#xff0c;是一种常用在语音识别、文本识别等领域的算法&#xff0c;用来解决输入和输出序列长度不一、无法对齐的问题。在CRNN中&#xff0c;它实际上就是模型对应的损失函数(CTC loss)。 一、背景 字母和语音的对齐(align)非…

Redis 内存的优化

目录 前言 Redis 的内存碎片问题 判断Redis 内存碎片 如何清理内存碎片&#xff1f; 前言 我想讲一下怎么提高Redis 内存的利用率&#xff0c;redis 的数据是保存在内存中。对内存的利用率低&#xff0c;意味着存的数据很少&#xff0c;并不意味着就没有内存了&#xff0c…

React-路由导航

1.声明式路由导航 1.1概念 说明&#xff1a;声明式导航是指通过在模版中通过<Link/>组件描述出要跳转到哪里去&#xff0c;比如后台管理系统的左侧菜单通常使用这种方式进行。 import {Link} from "react-router-dom" const Login()>{return (<div>…

[nlp入门论文精读] | Transformer

写在前面 最近工作从CV转向了NLP&#xff0c;于是空余时间便跟着哔哩哔哩李沐老师的视频学习。其实研一NLP课程讲论文的时候&#xff0c;我们小组就选择了经典的Attention和Bert&#xff0c;但还有很多细节并不完全理解&#xff0c;实际使用时也很困惑。 因此这个系列就来记…

Spring学习 基础(三)MVC

5、Spring MVC 传统Web模式&#xff1a; Model:系统涉及的数据&#xff0c;也就是 dao 和 bean。View&#xff1a;展示模型中的数据&#xff0c;只是用来展示。Controller&#xff1a;处理用户请求都发送给 &#xff0c;返回数据给 JSP 并展示给用户。 随着 Spring 轻量级开发…

【python】time库知识整理

简介 python的time库是python内置库&#xff0c;主要负责处理与时间相关的事务。 获取当前时间 函数作用time()获取当前时间戳ctime()获取字符串形式的时间gmtime()调用内部方法&#xff0c;赋予属性&#xff0c;能够被程序调用执行 time返回的是时间戳 ctime是返回的我们…

智慧安防视频远程监控平台EasyCVR集成后播放只有一帧画面是什么原因?

智慧安防视频监控平台EasyCVR能在复杂的网络环境中&#xff08;专网、局域网、广域网、VPN、公网等&#xff09;将前端海量的设备进行统一集中接入与视频汇聚管理&#xff0c;平台可支持的接入协议包括&#xff1a;国标GB28181、RTSP/Onvif、RTMP&#xff0c;以及厂家的私有协议…

Linux网络套接字之预备知识

(&#xff61;&#xff65;∀&#xff65;)&#xff89;&#xff9e;嗨&#xff01;你好这里是ky233的主页&#xff1a;这里是ky233的主页&#xff0c;欢迎光临~https://blog.csdn.net/ky233?typeblog 点个关注不迷路⌯▾⌯ 目录 一、预备知识 1.理解源IP地址和目的IP地址 …

Day27:安全开发-PHP应用TP框架路由访问对象操作内置过滤绕过核心漏洞

目录 TP框架-开发-配置架构&路由&MVC模型 TP框架-安全-不安全写法&版本过滤绕过 思维导图 PHP知识点 功能&#xff1a;新闻列表&#xff0c;会员中心&#xff0c;资源下载&#xff0c;留言版&#xff0c;后台模块&#xff0c;模版引用&#xff0c;框架开发等 技…

Android14之解决报错:No module named sepolgen(一百九十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

excel统计分析——嵌套设计

参考资料&#xff1a;生物统计学&#xff0c;巢式嵌套设计的方差分析 嵌套设计&#xff08;nested design&#xff09;也称为系统分组设计或巢式设计&#xff0c;是把试验空间逐级向低层次划分的试验设计方法。与裂区设计相似&#xff0c;先按一级因素设计试验&#xff0c;然后…

LeetCode-1004. 最大连续1的个数 III

每日一题系列&#xff08;day 20&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50…

【OpenCV】如何在Linux操作系统下正确安装 OpenCV

前言 我是在虚拟机上跑的 Linux 5.8.0-44-generic。 配置如下&#xff1a; 目录 第一步&#xff1a;下载依赖文件 第二步&#xff1a;下载 opencv 和 opencv_contrib 源码 第三步&#xff1a;解压缩包 第四步&#xff1a;移动文件 第五步&#xff1a;生成 makefile 文件 …

oracle基础-多表关联查询 备份

一、概述 在实际应用系统开发中会设计多个数据表&#xff0c;每个表的信息不是独立存在的&#xff0c;而是若干个表之间的信息存在一定的关系&#xff0c;当用户查询某一个表的信息时&#xff0c;很可能需要查询关联数据表的信息&#xff0c;这就是多表关联查询。SELECT语句自身…

Prometheus添加nginx节点显示不支持stub_status 解决办法

1、我们在使用Prometheus监控添加nginx节点监控的时候&#xff0c;在被监控节点的nginx配置文件中添加下面的模块 server { listen 80; server_name localhost; location /stub_status { stub_status on; access_log off; …

【解读】OWASP 大语言模型(LLM)安全测评基准V1.0

大语言模型&#xff08;LLM&#xff0c;Large Language Model&#xff09;是指参数量巨大、能够处理海量数据的模型, 此类模型通常具有大规模的参数&#xff0c;使得它们能够处理更复杂的问题&#xff0c;并学习更广泛的知识。自2022 年以来&#xff0c;LLM技术在得到了广泛的应…

网络触手获取天气数据存入mysql 项目

首先这个案例不一定能直接拿来用&#xff0c;虽然我觉得可以但是里面肯定有一些我没考虑到的地方。 有问题评论或者私信我&#xff1a; 这个案例适合我这种学生小白 获取天气数据网址&#xff1a; https://lishi.tianqi.com/xianyang/202201.html 网络触手获取天气数据代码直…

这是一段神奇的提示词,能直接调取Claude 3的系统提示词!附详细解读

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

第一代高通S7和S7 Pro音频平台:超旗舰性能,全面革新音频体验

以下文章来源于高通中国 如今&#xff0c;音频内容与形式日渐丰富&#xff0c;可满足人们放松心情、提升自我、获取资讯等需求。得益于手机、手表、耳机、车载音箱等智能设备的广泛应用&#xff0c;音频内容可以更快速触达用户。从《音频产品使用现状调研报告2023》中发现&…

蓝桥杯大赛软件python赛道真题:蛇形填数

真题链接&#xff1a;https://www.lanqiao.cn/problems/594/learning/ 题目描述&#xff1a; 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 如下图所示&#xff0c;小明用从1开始的正整数“蛇形”填充无限大的矩阵。 1 2 6 …