【自学开发之旅】Flask-数据查询-数据序列化-数据库关系(四)

news2025/1/21 0:47:46

db.session
ProductInfo.query
filter() 灵活查询
filter_by()
limit() 限制输出条目
offset() 偏移量
order_by() 排序
group_by() 分组聚合

<模型类>.query.<过滤方法>

过滤方法
请添加图片描述

查询方法
请添加图片描述
“牛”字开头(“,”默认)价格大于5的

>>> ProductInfo.query.filter(ProductInfo.product_name.startswith('牛'), ProductInfo.product_price > 5).all()
[<ProductInfo 3>, <ProductInfo 5>]
>>> result = ProductInfo.query.filter(ProductInfo.product_name.startswith('牛'), ProductInfo.product_price > 5).al
l()
>>> [pro.product_name for pro in result]
['牛肌肉', '牛肉']

用“或”的话需要:导入or_()

>>> from sqlalchemy import or_
>>> ProductInfo.query.filter(or_(ProductInfo.product_name.startswith('牛'), ProductInfo.product_price > 5)).all()
[<ProductInfo 1>, <ProductInfo 3>, <ProductInfo 5>]
>>> result = ProductInfo.query.filter(or_(ProductInfo.product_name.startswith('牛'), ProductInfo.product_price > 5
)).all()
>>> [pro.product_name for pro in result]
['apple', '牛肌肉', '牛肉']

in_的用法:在某个范围

>>> ProductInfo.query.filter(ProductInfo.product_address.in_(['湖南','山东','集美'])).all()
[<ProductInfo 1>, <ProductInfo 2>, <ProductInfo 3>, <ProductInfo 5>, <ProductInfo 6>, <ProductInfo 7>]
>>> result = ProductInfo.query.filter(ProductInfo.product_address.in_(['湖南','山东','集美'])).all()
>>> [pro.product_name for pro in result]
['apple', 'orange', '牛肌肉', '牛肉', '鸡肉', '鸡胸肉']

分页
类.query.filter.(类.属性==“”).offset(3)limit(3).all()
limit限制每页多少条,offset限制多少第多少页


查询product_price > 5的所有记录
两种方法

>>> result = ProductInfo.query.filter(ProductInfo.product_price > 5).all()
>>> ProductInfo.query.filter(ProductInfo.product_price > 5).all()
[<ProductInfo 1>, <ProductInfo 3>, <ProductInfo 5>]
>>> [pro.product_name for pro in result]
['apple', '牛肌肉', '牛肉']

>>> db.session.query(ProductInfo.product_name).filter(ProductInfo.product_price > 5).all()
[('apple',), ('牛肌肉',), ('牛肉',)]

因为查出来还是元组,还需要继续处理

original_list = [('apple',), ('牛肌肉',), ('牛肉',)]  
new_list = [item[0] for item in original_list]  
print(new_list)

分组聚合
用db.session.query(查询列,聚合列)
.filter(条件) #分组前数据筛选条件
.group_by(“分组列名”) #按什么来分组
.having(条件) #分组之后过滤条件
group by常常和func一起使用
fun,sum()
avg()
max()
min()
count()

查询每个省份的价格平均值

>>> from models.product import ProductInfo
>>> from models import db
>>> from sqlalchemy import func
>>> db.session.query(ProductInfo.product_address, func.avg(ProductInfo.product_price)).group_by("product_address").all()
[('山东', 10.0), ('深圳', 3.0), ('湖南', 11.25), ('集美', 2.5)]

对该结果再减小范围,结果大于5的,用having

>>> db.session.query(ProductInfo.product_address,func.avg(ProductInfo.product_price)).group_by("product_address").having(func.avg(ProductInfo.product_price>5)).all()
[('山东', 10.0)]
>>>

 db.session.query(ProductInfo.product_address, ProductInfo.product_name, func.max(ProductInfo.product_price)).group_by("product_address").all()

报错:
在这里插入图片描述
解决:

问题是关于SQLAlchemy和MySQL的一个特定问题,具有一定的代码相关性。
这个错误是因为你的SQL查询中有一个在GROUP BY子句中未被聚合的列,这是MySQL的’only_full_group_by’模式所不允许的。由于product_name未包含在GROUP BY子句中,也未在聚合函数(如MAX、MIN、AVG等)中使用,所以MySQL抛出了这个错误。

移除此模式:MySQL的’only_full_group_by’模式是可以更改的。这个模式是在MySQL 5.7.5版本以后引入的,用于限制GROUP BY查询的行为。它要求SELECT列表中的所有非聚合列都必须在GROUP BY子句中出现,否则就会抛出错误。

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

这将从全局的SQL模式中移除’ONLY_FULL_GROUP_BY’选项。
4.运行以下命令来检查当前的SQL模式:

SELECT @@sql_mode;

练习:
查询记录添加时间在1天以前所有记录

>>> ProductInfo.query.filter(ProductInfo.add_time<=(datetime.datetime.now() - datetime.timedelta(days=1))).all()

[<ProductInfo 5>]

查询种类为fruits的前十条记录

ProductInfo.query.filter(ProductInfo.product_kind==1).limit(10).all()
[<ProductInfo 1>, <ProductInfo 2>, <ProductInfo 8>]

查询产地为湖南的第一条记录

ProductInfo.query.filter(ProductInfo.product_address == "湖南").first()
<ProductInfo 2>

查询价格大于10的所有记录,并且倒序(降序desc)排序(order_by)

>>> ProductInfo.query.filter(ProductInfo.product_price>10).order_by(ProductInfo.product_price.desc()).all()
[<ProductInfo 5>, <ProductInfo 3>]

数据序列化
让对象可以跨平台存储,或者进行网络传输

orm实现查询功能
router/product_view/product.py

@product_bp.route("/product/get")
def product_get():
    # 通过url携带的参数来传递id
    id = request.args.get("id")
    if id is None:
        result = ProductInfo.query.all()
    else:
        result = ProductInfo.query.get(id)#result是个对象(结构体)每个平台都不一样,底层实现不一样,不能来传输和返回
        #result = ProductInfo.query.filter(ProductInfo.product_id == id).all

	#数据序列化:json、pickle库
    if result:
    	#对象 - 字典 - json
    	#方法一:自定义实现
    	#tmp_dict = {}
    	#tmp_dict["product_name"] = result.product_name
        
        #方法二:通过dict函数将对象变成字典。对象要实现keys和__getitem__的方法
        # return generate_response(msg="get success!", data=result)
        if isinstance(result, list):
        	result2 = [dict(pro) for pro in result]
        else:
        	result2 = dict(result)
        return generate_response(msg='get success!', data=result2)
    else:
        return generate_response(msg='data empty!', code=6)

使用方法二:
去models/prudct.py去实现那两种方法

    # dict函数转化字典的时候,自动调用对象中的keys方法,自定字典中的key,然后依照字典的取值方式(__getitem__去获取对应的key值)
    def keys(self):
        return ('product_name','product_kind','product_price','product_address')
    def __getitem__(self, item):
        return getattr(self,item)

在这里插入图片描述

关键字搜索功能接口实现

@product_bp.route("/product/k_search", methods=["GET"])
def k_search():
    pro_search = request.args.get("search")
    if pro_search is None:
        result = ProductInfo.query.all()
    else:
        result = ProductInfo.query.filter(or_(ProductInfo.product_address.like(f'%{pro_search}%'), ProductInfo.product_name.like(f'%{pro_search}%')))
    result2 = [dict(pro) for pro in result]
    return generate_response(code=10000, msg="get product info success", data=result2)

在这里插入图片描述
数据库关系
创建一个种类表,用来查询的时候kind1–fruits

在models/product.py添加

class ProKind(db.Model):
    __tablename__ = "pro_kind"
    kind_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    kind_name = db.Column(db.String(256))
    

外键创造联系—relationship
一对一、一对多、多对多

在ProductInfo类中添加(把kind那里改下)

	# 建立外键关联
    kind_forkey = db.Column(db.ForeignKey('pro_kind.kind_id'))

在ProKind类中添加

    # 建立relationship
    pro_info = db.relationship("ProductInfo", backref="kind")

“backref”是反向查询字段
对于ProKind类的对象可以通过pro_info属性查询到关联的ProductInfo,同时它为ProductInfo对象建立了kind属性,ProductInfo对象可以通过kind属性查询响应的ProKind信息

>>> p1 = ProductInfo.query.get(1)
>>> dir(p1)
['__abstract__', '__annotations__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
 '__format__', '__fsa__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '_
_init_subclass__', '__le__', '__lt__', '__mapper__', '__module__', '__ne__', '__new__', '__reduce__', '__re
duce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__table__', '__tablena
me__', '__weakref__', '_sa_class_manager', '_sa_instance_state', '_sa_registry', 'add_time', 'keys', **'kind'**
, 'metadata', 'product_address', 'product_id', 'product_kind', 'product_name', 'product_price', 'query', 'q
uery_class', 'registry']
>>> p1.kind
<ProKind 1>
>>> p1.kind.kind_name
'fruits'
>>>

上面这个是一对多的联系,如果一对一:

    # 建立relationship
    pro_info = db.relationship("ProductInfo", backref="kind", userlist=False)

注意都在orm层,不用连表,我们关联到另一个表是指属性字段而已pro_info,数据库中不用创建外键。

>>> k1 = ProKind.query.get(1)
>>> k1
<ProKind 1>
>>> dir(k1)
['__abstract__', '__annotations__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
 '__format__', '__fsa__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass_
_', '__le__', '__lt__', '__mapper__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__
repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__table__', '__tablename__', '__weakr
ef__', '_sa_class_manager', '_sa_instance_state', '_sa_registry', 'kind_id', 'kind_name', 'metadata', **'pro_
info'**, 'query', 'query_class', 'registry']
>>> k1.pro_info

那接下来怎么查:
将获取属性的时候稍微变一变
models/product.py

    def __getitem__(self, item):
        if item == 'product_kind':
            return self.kind.kind_name
        else:
            return getattr(self,item)

在这里插入图片描述

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

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

相关文章

JS判断当前是早上,中午,下午还是晚上

<!DOCTYPE html> <html><head><meta charset"utf-8" /><title></title></head><body><div></div><script>function getTimeState() {// 获取当前时间let timeNow new Date();// 获取当前小时let…

Pytest系列-fixture的详细使用和结合conftest.py的详细使用(3)

介绍 前面一篇讲了setup、teardown可以实现在执行用例前或结束后加入一些操作&#xff0c;但这种都是针对整个脚本全局生效的。 Fixture是pytest的非常核心功能之一&#xff0c;在不改变被装饰函数的前提下对函数进行功能增强&#xff0c;经常用于自定义测试用例前置和后置工作…

【C++】string类模拟实现上篇(附完整源码)

目录 前言1. string的基本结构2. 构造函数、析构函数2.1 构造函数的实现2.1.1带参构造函数 2.2析构函数2.3无参构造函数2.4无参和带参构造函数合并 3. string的遍历3.1 operator[ ]3.2迭代器模拟实现 (简单实现&#xff09;3.3 const迭代器模拟实现 4. 数据的增删查改4.1 reser…

最经典的解析LSA数据库(第六课)

初步认识OSPF的大致内容(第三课)_IHOPEDREAM的博客-CSDN博客 1 OSPF 工作过程 建立领居表 同步数据库 今天来 说一说数据库概念 计算路由表 2 什么是数据库&#xff1f; 数据库是一个组织化的数据集合&#xff0c;用于存储、管理和检索数据。它是一个可访问的集合&#x…

[SICTF 2023 #Round2] Crypto,PWN,Reverse

似乎很久没写了。 周五到周日&#xff0c;两天的这个比赛&#xff0c;有些东西还真是头回用&#xff0c;值得纪录一下。 Crypto 密码这块这届还是比较简单的&#xff0c;没有复杂的题&#xff0c;但量大分多。 【签到】古典大杂烩 给了一堆emoji的图 &#x1f429;&#x…

英国私校的艺术奖学金有哪些?申请要求和申请流程详解!

众所周知&#xff0c;英国私校不仅学术拔尖&#xff0c;在对学生艺术方面的培养也是毫不逊色的。几乎打开每一所英国私校的官网&#xff0c;都可以看到学校罗列的提供的各类课外艺术活动的精彩照片。      每个英国私校除了课后开设的五花八门的兴趣课外&#xff0c;还有各…

【项目 计网12】4.32UDP通信实现 4.33广播 4.34组播 4.35本地套接字通信

文章目录 4.32UDP通信实现udp_client.cudp_server.c 4.33广播bro_server.cbro_client.c 4.34组播multi_server.cmulti_client.c 4.35本地套接字通信ipc_server.cipc_client.c 4.32UDP通信实现 udp_client.c #include <stdio.h> #include <stdlib.h> #include <…

2023-09-10 LeetCode每日一题(课程表 II)

2023-09-10每日一题 一、题目编号 210. 课程表 II二、题目链接 点击跳转到题目位置 三、题目描述 现在你总共有 numCourses 门课需要选&#xff0c;记为 0 到 numCourses - 1。给你一个数组 prerequisites &#xff0c;其中 prerequisites[i] [ai, bi] &#xff0c;表示在…

hive葵花宝典:hive函数大全

文章目录 版权声明函数1 函数分类2 查看函数列表3 数学函数取整函数: round指定精度取整函数: round向下取整函数: floor向上取整函数: ceil取随机数函数: rand幂运算函数: pow绝对值函数: abs 4 字符串函数字符串长度函数&#xff1a;length字符串反转函数&#xff1a;reverse…

表情识别-情感分析-人脸识别(代码+教程)

表情识别 面部情绪识别&#xff08;FER&#xff09;是指根据面部表情识别和分类人类情绪的过程。通过分析面部特征和模式&#xff0c;机器可以对一个人的情绪状态作出有根据的推断。这个面部识别的子领域高度跨学科&#xff0c;涉及计算机视觉、机器学习和心理学等领域的知识。…

解析Spring Boot中的Profile:配置文件与代码的双重掌控

目录 创建一个spring boot 项目spring boot 中的配置体系配置文件与 Profile代码控制与Profile 创建一个spring boot 项目 基于 Spring Boot 创建 Web 应用程序的方法有很多,我们选择在idea中直接进行创建&#xff0c;服务器URL选择Spring Initializer 网站&#xff0c;类型选…

libnetcdf.so.19: cannot open shared object file: No such file or directory

Linux编译程序时出现问题 在linux系统上&#xff0c;编译一个工具包后&#xff0c;在运行该工具包时&#xff0c;出现以下报错&#xff1a; libnetcdf.so.19: cannot open shared object file: No such file or directory仔细分析报错信息可以发现&#xff1a;在运行该工具包…

UG\NX二次开发 判断向量在指定的公差内是否为零,判断是否是零向量 UF_VEC3_is_zero

文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 简介: UG\NX二次开发 判断向量在指定的公差内是否为零,判断是否是零向量 UF_VEC3_is_zero 效果: 代码: #include "me.hpp"void ufusr(char* param, int* retco…

Pytorch实现基于LSTM的情感分析

文章目录 本文参考导入必要的包介绍torchnet做数据的导入给必要的参数命名加载文本数据数据前处理模型训练验证 本文参考 PyTorch深度学习项目实战100例 https://weibaohang.blog.csdn.net/article/details/127154284?spm1001.2014.3001.5501 这段代码是一个基于PyTorch实现…

LeetCode(力扣)37. 解数独Python

LeetCode37. 解数独 题目链接代码 题目链接 https://leetcode.cn/problems/sudoku-solver/description/ 代码 class Solution:def solveSudoku(self, board: List[List[str]]) -> None:"""Do not return anything, modify board in-place instead."…

使用数据库表快速生成代码

这里使用的EasyCode插件&#xff0c;直接下载即可&#xff0c;这里需要有数据库的技术与使用idea&#xff0c;会使用起来更流畅&#xff01; 使用idea连接数据库 右键选择表 勾选你所需要的添加&#xff0c; 鄙人一般除了debug&#xff0c;其他都会勾选上 点击确定&#xff0c;…

【电源专题】不合理接地引发的典型问题及地环路隔离的方法

在文章:【电源专题】接地的类型 中我们讲到因为历史的原因接地在不同时期的概念是不同的。到了如今大规模的集成电路时代,在单板中接地其实是想要一个参考电位,一个等势点。 但是理想终究是理想,在现实接地中,往往因为接地平面的阻抗不是0,而电源电流过大、信号频率过高…

目标检测笔记(十五): 使用YOLOX完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)

文章目录 一、目标检测介绍二、YOLOX介绍三、源码获取四、环境搭建4.1 环境检测 五、数据集准备六、模型训练七、模型验证八、模型测试 一、目标检测介绍 目标检测&#xff08;Object Detection&#xff09;是计算机视觉领域的一项重要技术&#xff0c;旨在识别图像或视频中的…

Linux权限的概念和管理

Linux权限的概念和管理 1. Linux权限的概念2. Linux权限管理2.1 文件访问者的分类&#xff08;人&#xff09;2.2 文件类型和访问权限&#xff08;事物属性&#xff09;2.2.1 文件类型2.2.2 基本权限 2.3 文件权限值的表示方法2.4文件访问权限的相关设置方法1. chmod&#xff0…

C++的运算符重载介绍

所谓重载,就是赋予新的含义。函数重载(Function Overloading)可以让一个函数名有多种功能,在不同情况下进行不同的操作。运算符重载(Operator Overloading)也是一个道理,同一个运算符可以有不同的功能。 实际上,我们已经在不知不觉中使用了运算符重载。例如,+号可以对…