Python + pymysql 之 MySQL 查询操作

news2024/9/23 7:32:59

在MySQL中构建一个测试表,如下:

查询单条数据

# -*- coding: UTF-8 -*-
import pymysql


def mysql_query():
    """
    MySQL查询
    :return:
    """
    # 打开数据库连接
    db = pymysql.connect(host="127.0.0.1",
                         user="root",
                         password="testtest",
                         database="testdb")
    # 使用 cursor() 方法创建一个游标对象 cursor
    cursor = db.cursor()
    # SQL语句
    sql = """
    select * from student_info;
    """
    # 使用 execute()  方法执行 SQL 查询
    cursor.execute(sql)
    # 获取第一条结果
    student = cursor.fetchone()
    print(type(student))
    print(student)
    # 关闭数据库连接
    db.close()
    # 返回查询结果
    return student


if __name__ == '__main__':
    mysql_query()


 打印输出结果:

<class 'tuple'>
(1, '张三', '2233445566', 18)

从中可以看出,默认情况下,查询结果返回的是元组tuple形式

返回元组会有一个问题,当你只查询一个属性字段时,返回的结果会是有逗号的元组

例如:sql改变一下

    sql = """
    select name from student_info where id =2;
    """

此时,打印输出结果:

<class 'tuple'>
('李四',)

此时,建议return前,简单处理一下,我们只取返回结果元组的第一个元素

student = cursor.fetchone()[0]

此时,打印输出结果:

<class 'str'>
李四

这样一来,函数的输出结果就可以直接使用啦

那么,还有没有其他返回形式呢,答案是有的

还可以返回字典形式,在代码中创建游标时,传入参数,指定返回字典形式

cursor = db.cursor(pymysql.cursors.DictCursor)

此时,打印输出结果:

<class 'dict'>
{'name': '李四'}

查询全部数据

把其中的

student = cursor.fetchone()

替换为

students = cursor.fetchall()

此时返回全部数据,默认为元组形式

((1, '张三', '2233445566', 18), (2, '李四', '12341234', 19), (3, '王五', '11112222', 20))

同样需要注意,如果只是查询一个属性字段的话,返回的是元组形式

(('张三',), ('李四',), ('王五',))

此时,可以用一个循环,来提取属性内容到

names = [student[0] for student in students]

此时,打印names结果为:

['张三', '李四', '王五']

传参查询

例如:根据学生id查询学生姓名

传参的方式:

# SQL语句
sql = """
select name from student_info where id = %s;
"""
# 使用 execute()  方法执行 SQL 查询
cursor.execute(sql, [id])

注意:此处的占位符是%s,无论是字符串、数字或者其他类型,都是这个占位符。 %s不能加引号。

上代码

def get_name_by_id(id):
    """
    根据学生id查询学生姓名
    :param id:
    :return:
    """
    # 打开数据库连接
    db = pymysql.connect(host="127.0.0.1",
                         user="root",
                         password="testtest",
                         database="testdb")
    # 使用 cursor() 方法创建一个游标对象 cursor 以元组形式返回
    cursor = db.cursor()
    # SQL语句
    sql = """
    select name from student_info where id = %s;
    """
    # 使用 execute()  方法执行 SQL 查询
    cursor.execute(sql, [id])
    # 获取第一条结果
    name = cursor.fetchone()[0]
    # 关闭数据库连接
    db.close()
    # 返回查询结果
    return name


if __name__ == '__main__':
    id = 3
    name = get_name_by_id(id)
    print(name)

返回打印结果:

王五

为什么不用拼接字符串的方式来组装sql语句呢?

为了防注入,建议大家养成习惯

拿一个典型的登录注入来举例:

    username = 'zhangsan'
    password = '123456'
    sql = "SELECT user_id FROM users WHERE username = '{}' AND password = '{}';".format(username, password)

看起来也没毛病,但是如果此时,username传入的是如下内容:

username = 'zhangsan OR 1 = 1 -- a'

sql就会变成这个样子了:

SELECT user_id FROM users WHERE username = 'zhangsan OR 1 = 1 -- a' AND password = '123456';

美化一下SQL

SELECT
	user_id 
FROM
	users 
WHERE
	username = 'zhangsan' 
	OR 1 = 1 -- a AND password = 'abc';

这段sql的效果是无论输入什么密码,都会返回登录成功。

改成使用pymysql列表方式传参就不怕注入啦

def get_user_id(username, password):
    # 打开数据库连接
    db = pymysql.connect(host="127.0.0.1",
                         user="root",
                         password="testtest",
                         database="testdb")
    # 使用 cursor() 方法创建一个游标对象 cursor 以元组形式返回
    cursor = db.cursor()
    # SQL语句
    sql = """
    SELECT user_id FROM users WHERE username = %s AND password = %s;
    """
    # 使用 execute()  方法执行 SQL 查询
    cursor.execute(sql, [username, password])
    # 获取第一条结果
    user_id = cursor.fetchone()
    # 关闭数据库连接
    db.close()
    # 返回查询结果
    return user_id


if __name__ == '__main__':
    username = 'zhangsan OR 1 = 1 -- a'
    password = 'abc'
    user_id = get_user_id(username, password)
    print(bool(user_id))

返回打印结果为:

False

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

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

相关文章

IDEA 配置 openjdk,jre

使用 idea 配置 zip 版本的 openjdk 和 jre&#xff0c;我使用的时 redhat 提供的 jdk 和 jre。 一、下载 idea、jdk 和 jre 红帽下载地址为&#xff1a; jdk 和 jre 安装地址根据个人配置&#xff0c;我的配置如下&#xff1a; 下划线的分别为我的 jdk 和 jre 保存路径 二…

简单学习UE5.2的PCG框架插件里的基础概念

目标 最近了解到5.2版本推出了实验性的功能PCG框架&#xff0c;以及用它做的范例 Electric Dreams。 本篇我简单学习它的一些基础概念&#xff0c;做一些记录。 0. 启用插件 此功能相关的类型都在PCG插件中&#xff0c;因此首先要确保启用了PCG插件&#xff1a; 1. PCGGr…

为什么进程地址空间中包括操作系统?

今天聊聊进程地址空间这点小事。 说到进程的地址空间&#xff0c;大家可能都知道这样一张图&#xff1a; 这张图就是Linux程序运行起来后所谓的进程地址空间&#xff0c;这里包括我们熟悉的代码区、数据区、以及堆区和栈区&#xff0c;今天我们不讲解这些区域&#xff0c;而是…

Vue生态及实践 - SSR(上)

目录 目标 理论 Rendering 你真的需要SSR亦或是同构吗&#xff1f; 同构实践 通用代码 同构第一步&#xff1a;避免单例 src/app.js src/store.js src/router.js 同构第二步&#xff1a;Server entry【服务端进入】&#xff1b;Client entry【客户端进入】 src/entry…

ESP32设备驱动-AS5600磁性旋转位置传感器

AS5600磁性旋转位置传感器 文章目录 AS5600磁性旋转位置传感器1、AS5600介绍2、硬件准备3、软件准备4、驱动实现1、AS5600介绍 AS5600 是一款可编程的 12 位高分辨率非接触式磁性旋转位置传感器。 AS5600可以作为磁性电位器或磁性编码器使用,具有出色的可靠性和耐用性。 与传…

网页版代码编辑器实现

接着前几天写的博客https://blog.csdn.net/woyebuzhidao321/article/details/131495855&#xff0c;提到了涉及vscode网页版工作区创建的api&#xff0c;这两天一时兴起&#xff0c;搞了一个网页版的代码编辑器&#xff0c;如果在2020年10月之前&#xff0c;实现一个网页版代码…

活动笔记 | 「企业人效提升路径」之数字化实践

6月27日&#xff0c;由人力资源智享会联合盖雅工场等机构主办的2023中国人力资源数字化论坛在北京顺利举办。盖雅工场高级解决方案顾问谷天毅先生发表了主题为 《企业人效提升路径之数字化实践》 的分享。 以下是分享内容&#xff0c;enjoy~ △ 盖雅工场高级解决方案顾问谷天…

httpx 返回都是乱码问题,非编码问题。

因为python 的requests 不能使用抓http2 的报文。所以看了一些httpx的使用。但是发现httpx 不能自动解压&#xff0c;text打印出来的都是乱码。一开始以为是编码格式的bug &#xff0c;但是使用chardet 确认了确实是utf-8.然后怀疑是压缩的问题。先去官网搜了一些文档 文档说会…

opencv4.7.0编译opencv-contrib-4.7.0以及CUDA

0、引言 最近工作中需要用到使用CUDA加速后的opencv进行传统算法的开发&#xff0c;在编程之前&#xff0c;需要先解决环境编译和lib库问题&#xff0c;本文就是记录自己编译opencv-4.7.0的全过程。 1、CUDA下载和安装 可参考我之前的博客WIN10安装配置TensorRT详解中的前几…

达尔文——生物医疗科学领域大模型

赛灵力官网 1. 生物医疗领域的挑战 1.1 复杂性 生物系统和生物过程非常复杂&#xff0c;包含大量的相互作用和调控机制&#xff0c;理解和解析这些复杂性是一项巨大的挑战。 举例来说&#xff0c;单单一个人类&#xff0c;体内的生物信息就非常复杂&#xff1a; 人类体内体内…

Django_re_path_使用正则匹配url

与path定义的路由相比&#xff0c;re_path 定义的路由可以使用正则表达式匹配url。 需要注意的是&#xff1a; 如果未定义匹配结果的变量名&#xff0c;匹配的结果默认传入视图的第2个形参。如果定义了匹配结果的变量名&#xff0c;匹配的结果会传给视图的同名字段&#xff0…

从零开始学习自动驾驶决策规划

从零开始学习自动驾驶决策规划 从入门到掌握的一系列讲解&#xff0c;其中涵盖的内容如下&#xff1a; 前言课 第一节-ros工程的创建 第一节-运行环境和工程目录简介第二节-工程运行和小车模型搭建简介 第二节-车辆里程计第三节-整体架构思路 第三节-地图路线构建方法 第三节…

Packet Tracer – 配置静态 NAT

Packet Tracer – 配置静态 NAT 目标 第 1 部分&#xff1a;测试不使用 NAT 的访问 第 2 部分&#xff1a;配置静态 NAT 第 3 部分&#xff1a;测试使用 NAT 的访问 拓扑图 场景 在 IPv4 配置网络中&#xff0c;客户端和服务器使用专用编址。 然后&#xff0c;在含专用编址…

MATLAB---线性规划问题求最优解(含例题)

线性规划是运筹学的基础&#xff0c;在现实企业经营中&#xff0c;如何有效的利用有限的人力、财力、物力等资源。 MATLAB 为方便大家理解&#xff0c;这里我们直接用一个例题为大家讲解使用matlab求解线性规划问题。 根据上图给出的线性规划问题。我们使…

SpringBoot 如何使用 @ExceptionHandler 注解进行局部异常处理

SpringBoot 如何使用 ExceptionHandler 注解进行局部异常处理 介绍 在开发 Web 应用程序时&#xff0c;异常处理是非常重要的一部分。SpringBoot 提供了多种方式来处理异常&#xff0c;其中之一是使用 ExceptionHandler 注解进行局部异常处理。使用 ExceptionHandler 注解&am…

哈工大计算网络课程数据链路层详解之:数据链路层服务

哈工大计算网络课程数据链路层详解之&#xff1a;数据链路层服务 在介绍完网络层的实现功能和协议之后&#xff0c;接下来我们继续介绍网络层的下一层&#xff1a;数据链路层。 本节首先对数据链路层的功能和所提供的服务进行概述。 如下图示例网络所示&#xff0c;标红色的部…

【二分查找】34. 在排序数组中查找元素的第一个和最后一个位置

34. 在排序数组中查找元素的第一个和最后一个位置 解题思路 使用二分查找查找到目标元素的索引之后然后向左以及向右寻找目标元素&#xff0c;然后记录下区间位置 然后保存下来 class Solution {public int[] searchRange(int[] nums, int target) {// 使用二分查找 数组有序…

Java使用Stream API对于数据列表经常处理

Java使用Stream API对于数据列表经常处理 先提供一些简单到复杂的常见例子&#xff0c;您可以根据这些例子进行进一步的开发和学习&#xff1a; 数据过滤筛选操作 查询表中所有数据&#xff1a; List<User> users userDao.getAllUsers();根据条件查询单个结果&#…

别测了,背锅上线!

三百六十行&#xff0c;行行都背锅。 用例千万条&#xff0c;质量第一条。 流程不规范&#xff0c;亲人两行泪&#xff01; 每次上线后多多少少都有些问题&#xff0c;每次的项目总结会总会生产一口新锅&#xff0c;等着你我他来背&#xff0c;这不又要上线了&#xff0c;这次…

华为OD机试真题 Java 实现【快递投放问题】【2023 B卷 100分】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述四、Java算法源码五、效果展示1、输入2、输出 一、题目描述 有N个快递站点用字符串标识&#xff0c;某些站点之间有道路连接。每个站点有一些包裹要运输&#xff0c;每个站点间的包裹不重复&#xff0c;路上有检查站会导致部分货物无…