【Python进阶】正则表达式、pymysql模块

目录

一、正则表达式的概述

1、基本介绍

2、快速使用re模块

二、正则的常见规则

1、匹配单个字符

2、原始字符串

3、匹配多个字符

4、匹配开头和结尾

5、匹配分组

三、Python与MySQL交互

1、pymysql模块的安装

2、pymysql的操作步骤

3、connection对象

4、cursor对象

四、数据记录操作

1、准备数据表

2、插入数据

3、修改数据

4、删除数据

5、SQL注入

6、语句参数化

7、查询数据

五、注册与登录案例

1、注册

2、登录

一、正则表达式的概述

1、基本介绍

正则表达式,也叫做规则表达式,通常会说成【正则】。

实际上,正则表达式就是指符合一定规则的字符串,同时它能用于检查一段文本数据是否与某种模式匹配。

比如,在网站注册新用户时,对用户名、手机号等的验证就使用了正则表达式。

在Python中,有一个专门用于处理正则表达式的模块:

# 导入模块
import re

在正则表达式中,可以使用单个字符或一段字符串来匹配满足正则规则的文本数据。而我们要学习的,就是正则规则。

在一些文本编辑器中,可以使用正则表达式来查找或替换一些文本。

总结:

(1)正则表达式就是一段具有特殊含义的字符串,即正则表达式 == 字符串;

(2)注意:在Python中,若要操作正则表达式,要使用re模块。

2、快速使用re模块

我们已经知道,可以使用re模块来操作正则表达式。

re模块常用方法:

函数名含义
match(pattern, string)返回一个已匹配成功的对象。其中,参数pattern表示正则字符串,参数string表示要匹配的内容。

当成功匹配数据后,结果存放在对象的函数:

函数名含义
group(num=0)匹配成功的内容,num默认是0,表示匹配的所有数据结果。

例如,一起来完成:

(1)使用正则快速验证手机号码是否合格;

(2)验证手机是否合格的条件有:手机号码以1开头且总位数为11位,全部为数字且不包含其他字符;

(3)根据要求,使用re模块完成对手机号码的验证。

import re
​
str1 = '13812345678'
regex_str = '1[3456789][0-9]{9}'  # 这种写法没有定义开头结尾限定,只要包含匹配的内容就行
regex_str = '^1[3456789][0-9]{9}$'  # 这种写法佳乐开头结尾限定,必须精准匹配才行
​
result = re.match(regex_str,str1)  # 判断str1这个字符串是否符合regex_str这个正则规则
if result is not None:print('字符串内容符合正则!')print(result.group())  # group 表示只获取字符串中匹配上的部分
else:print('字符串内容不符合正则!')
​

总结:

(1)如果要使用re模块来匹配数据,应该使用re模块的match()匹配方法;

(2)注意:当使用re模块未匹配到对应的数据时,会返回None。

二、正则的常见规则

1、匹配单个字符

常用的匹配单个字符的语法:

代码功能
.匹配除\n之外的任何单个字符。
[ ]匹配[ ]中列举的字符。
\d匹配一个数字字符,比如[0-9]。
\D匹配一个非数字字符,比如[^0-9]
\s匹配任何空白字符。(空格、tab、换行)
\S匹配任何非空白字符。
\w匹配非特殊字符,比如a-z、A-Z、0-9、_、汉字。
\W匹配特殊字符,比如非字母、非数字、非汉字等。

例如,一起来完成:

(1)使用.来匹配任意单个字符;

(2)使用[a-z]、[A-Z]、[^0-9]分别来查看小写字母、大写字母、非数字;

(3)使用\d来匹配一个数字字符;

(4)使用\w来匹配一个可能有数字、大小写字母、下划线的单个字符。

# 1.导入模块
import re
​
# 报错:正则有误;  能输出结果,表示正常
# print(f"结果:{xxx}")
​
# 2.任意字符print(f"结果:{re.match('.','h').group()}")print(f"结果:{re.match('.','1').group()}")print(f"结果:{re.match('.','_').group()}")print(f"结果:{re.match('.','python').group()}")
​
# 3.小写、大写、非数字print(f"结果:{re.match('[a-z]','a').group()}")print(f"结果:{re.match('[a-z]','y').group()}")print(f"结果:{re.match('[a-z]','Z').group()}")   # 报错print(f"结果:{re.match('[a-z]','abc').group()}")print(f"结果:{re.match('[A-Z]','B').group()}")print(f"结果:{re.match('[0-9]','1').group()}")print(f"结果:{re.match('[^0-9]','b').group()}")print(re.match('\D','b').group())
​
# 4.一个数字print(f"结果:{re.match('[0-9]','8').group()}")print(f"结果:{re.match('[0-9]','66').group()}")print(re.match('\d','6').group())5.单字符print(re.match('\w','6').group())print(re.match('\w','a').group())print(re.match('\w','N').group())print(re.match('\w','_').group())print(re.match('\w','深圳').group())

2、原始字符串

原始字符串指的是:在所有的正则表达式前,最好加上r,语法:

r"正则表达式"

例如,一起来完成:

(1)请使用正则来匹配路径名:E:\\

(2)请尝试使用不同方式去匹配数据,观察效果;

(3)思考:当要定义一段批量文本内容时,该怎么定义字符串?

print('E:\a.txt')    # 这里 会把 \a 当成一个字符, \是转义字符
print('E:\\a.txt')   # \\ 合成 一个  \
print(r'E:\a.txt')   # 前边加 r 表示 字符串中的任何字符没有特殊函数,就是普通字符串,不要过度解读

总结:

(1)当不想给一段文本数据内容转义而又要表达原始意义时,可以在文本数据内容前添加r。

(2)注意:当正确写了正则后又匹配不出数据结果时,可以试试在正则前添加r解决问题。

3、匹配多个字符

常用的匹配多个字符的语法:

代码功能
X*匹配X出现0次或无限次,即可有可无。
X+匹配X出现1次或无限次,即至少有1次。
X?匹配X出现1次或0次,即有一次或一次也没有。
X{m}匹配X恰好出现m次。
X{m,n}匹配X至少m次,但是不超过n次。

例如,一起来完成:

(1)使用X*来匹配出一个字符串:第1个字母为大小写字母,后面都是小写字母且这些字母可有可无;

(2)通过X+来匹配一个具有数字、大小写字母、下划线的字符串;

(3)通过X?来匹配0到99之间的任意数字;

(4)通过X{n,m}匹配出5到16位的密码,可以是大小写英文字母、数字、下划线。

import re
​result = re.match("","").group()print(f"结果:{result}")
# X*result = re.match("[a-zA-Z]","x").group()result = re.match("[a-zA-Z]","U").group()result = re.match("[a-zA-Z][a-z]*","U").group()result = re.match("[a-zA-Z][a-z]*","UzogY").group()print(f"结果:{result}")
# X+result = re.match("\w","123abcABC_hello").group()result = re.match("\w+","123abcABC_hello").group()print(f"结果:{result}")
# X?    0-9    10-99result = re.match("[1-9][0-9]","12").group()result = re.match("[1-9][0-9]","98").group()result = re.match("[1-9]?[0-9]","0").group()result = re.match("[1-9]?[0-9]","17").group()# result = re.match("[1-9]?[0-9]","09").group()print(f"结果:{result}")
# X{m,n}
result = re.match("[a-zA-Z0-9_]{5,16}","123456").group()
result = re.match("[a-zA-Z0-9_]{5,16}","1234fjwoefwoe23__fwjelf").group()   # ?如何解决?  $
print(f"结果:{result}")

==总结:==

(1)使用匹配多个字符的方式,可以一个字符或批量数据内容;

(2)注意:当要匹配批量数据内容时,应该优先使用:*。

4、匹配开头和结尾

代码功能
^匹配字符串开头。
$匹配字符串结尾。

例如,一起来完成:

(1)使用^来匹配非数字的单个字符;

(2)使用$来匹配www.baidu.com的结尾处。

import re# result = re.match("","").group()
# print(f"结果:{result}")# 匹配开头: 非数字
result = re.match("[0-9]","1aaa1").group()    # 默认是从第一个字符开始匹配,如果第一个字符不是数字就结束
print(f"结果:{result}")result = re.match("[^0-9]","g").group()    # 默认是从第一个字符开始匹配
print(f"结果:{result}")result = re.match("[^0-9]","heima").group()  # 默认是从第一个字符开始匹配
print(f"结果:{result}")result = re.match("[^0-9]+","heima").group()  # 默认是从第一个字符开始匹配
print(f"结果:{result}")print('----------------------')
# 匹配结尾
result = re.match(".+","www.baidu.com").group()
print(f"结果:{result}")result = re.match("www.baidu.com","www.baidu.com").group()
print(f"结果:{result}")result = re.match("www.baidu.com$","www.baidu.com.cn.gov.edu").group()  # 是否以某个串结尾
print(f"结果:{result}")result = re.match("^www.baidu.com$","www.baidu.com").group()
print(f"结果:{result}")

总结:

(1)当要限定结尾处内容时,可以使用$符号。

5、匹配分组

要获取分组数据信息,语法:

代码功能
X|Y匹配X或Y的任意一个表达式。
(X)将括号中字符X作为一个分组用于获取,且从1开始统计分组。

例如,一起来完成:

(1)使用X|Y来匹配出0-100之间的所有数字字符结果;

(2)使用(X)来匹配出含有163、126、qq这几个内容且用户名位数为4-12位的邮箱,如itcast@163.com等。

import reresult = re.match("","").group()
print(f"结果:{result}")0-100
result = re.match("hello|world","world").group()  # 只要hello和world有一个匹配上即可
print(f"结果:{result}")result = re.match("[1-9]?[0-9]|100","8").group()
print(f"结果:{result}")result = re.match("[1-9]?[0-9]|100","87").group()
print(f"结果:{result}")result = re.match("[1-9]?[0-9]|100","99").group()
print(f"结果:{result}")result = re.match("[1-9]?[0-9]|100","100").group()  # 10
print(f"结果:{result}")result = re.match("100|[1-9]?[0-9]","100").group()
print(f"结果:{result}")result = re.match("100|[1-9]?[0-9]","10").group()
print(f"结果:{result}")
print('----------------------------------------')
# 邮箱号
result = re.match("(\w{4,12})@(126|163|qq).(com|cn)","hellopy@qq.com").group()
print(result)
print(f"结果:{result[:result.find('@')]}")#  re.match('xxxx(表达式1)xxxx(表达式2)',字符串).group(1)# group(2) 里边的数字表示获取第2个括号中的内容
result = re.match("(\w{4,12})@(126|163|qq).com","hellopy@163.com").group(2)
print(result)
print(f"结果:{result[:result.find('@')]}")result = re.match("(\w{4,12})@(126|163|qq).com","hellopy@163.com").group(1)
print(f"结果:{result[:result.find('@')]}")result = re.match("(\w{4,12})@(126|163|qq).com","hellopy@163.com").group(2)
print(f"结果:{result[:result.find('@')]}")# group 中不加数字,返回匹配的所有内容
result = re.match("(\w{4,12})@(126|163|qq).com","hellopy@qq.com").group()
print(result)
print(f"结果:{result[:result.find('@')]}")

总结:

(1)如果在涉及到要获取分组数据时,一定记得要使用()来写正则;

(2)注意:要获取分组数据时,在正则中的()从1开始计算分组,比如获取第1组,则group()的括号中应该填写1。

三、Python与MySQL交互

1、pymysql模块的安装

当要使用Python和MySQL数据库进行交互,需要借助一个第三方模块:pymysql。

在使用pymysql模块前,先进行安装:

pip install pymysql

有时使用pip install xxx命令安装时较慢,若要提升pip下载的速度,可采用命令:

pip install 模块名 [-i 镜像源地址]
pip install pymysql -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pymysql -i http://mirrors.aliyun.com/pypi/simple/

比如,在国内的镜像源中,有很多可供使用的源地址:

镜像来源镜像源地址
豆瓣http://pypi.douban.com/simple/
阿里云Simple Index
清华大学Simple Index
中国科技大学Simple Index
华中理工大学http://pypi.hustunique.com/
山东理工大学http://pypi.sdutlinux.org/

当成功安装pymysql模块后,可直接导入使用:

# 导入模块
import pymysql

例如,一起来完成:

(1)在Python中,使用命令安装pymysql模块;

(2)当成功安装模块后,即可导入并验证是否已成功安装;

(3)思考:还有其他方式安装模块吗?

总结:

(1)当要在Python中安装pymysql模块,可以使用pip install pymsql命令;

(2)注意:当要使用pymysql模块时,可以直接导入使用,语法:import pymysql。

2、pymysql的操作步骤

在Python中,使用pymysql模块来操作MySQL数据的基本步骤:

对于图解,操作步骤说明:

(1)导入模块;

(2)创建连接对象;

(3)创建游标对象;

(4)使用游标对象执行SQL并进行增删改查;

(5)关闭游标对象;

(6)关闭连接对象。

例如,一起来了解:

(1)操作pymysql模块的基本步骤;

(2)对各个步骤做详细说明。

(1)导入模块;导入模块前, 优先安装pymysql模块: pip install pymysqlimport pymysql# 使用模块操作MySQL数据库
----------------------------------
(2)创建连接对象;db_conn = pymysql.connect()# 用户名 root# 密码 123456# IP地址 127.0.0.1    localhost# 端口号 3306# 数据库名 班级名_db_xxx# 编码格式 utf8   gbk
----------------------------------
(3)创建游标对象;db_cursor = db_conn.cursor()# 游标获取数据
----------------------------------
(4)使用游标对象执行SQL并进行增删改查;db_cursor.execute(xxxx)# 增 insert into 表名[(字段1, 字段2, ...)] values(值1, 值2,...)[,(值1, 值2,...),...][;]# 删 delete from 表名 [where 条件];# 改 update 表名 set 字段1=值1[, 字段2=值2, ...] [where 条件];# 查 select *[字段1, 字段2, ...] from 表名 [where 条件];
----------------------------------
(5)关闭游标对象;close()
----------------------------------
(6)关闭连接对象。close()

总结:

(1)当操作完pymysql后,需要对连接、游标等对象资源进行关闭,可以使用close()方法;

(2)注意:为了便于使用和操作pymysql模块,建议按照操作步骤来进行处理。

3、connection对象

我们都知道,在使用MySQL数据库前,首先需要登录并进行连接。[命令行、DataGrip]

类似地,在使用pymysql模块时,也需要登录并进行连接,且此时需要使用connection对象。

connection是用于建立与数据库的连接,需要使用pymysql模块来调用:

函数含义
connect(host=None, port=0, user=None, password="", database=None, charset='',...)用于创建Connection连接对象。 ①host:表示连接MySQL的IP地址。若为本机,则可表示成'localhost'或'127.0.0.1';若为其他计算机,则表示为具体IP地址; ②port:表示连接的MySQL的端口号,默认是3306; ③user:表示连接的用户名,默认是root; ④password:表示连接的密码; ⑤database:表示数据库的名称; ⑥charset:表示采用的编码方式,设定为'utf8'即可。

当成功通过connect()获取并得到连接对象后,常用函数:

函数含义
commit()用于事务提交,在进行数据操作时需要进行事务提交后才会生效。
close()用于关闭连接。
cursor()用于返回cursor对象,可使用该对象来执行SQL语句并获取结果。

说明:

(1)使用pymysql模块时,已默认开启了事务,因此要让数据操作生效,则必须要进行事务提交;

(2)为了节约系统内存资源,通常在使用完Connection连接对象后,要进行close()关闭连接。

总结:

(1)通常情况下,使用pymysql连接MySQL数据库,需要知道:IP地址、端口号、用户名、密码;

(2)注意:pymysql模块操作MySQL是默认已经开启了事务。

4、cursor对象

若要执行SQL语句时,则需要使用cursor对象,可通过connection对象的cursor()方法进行创建。

函数含义
cursor()用于返回cursor对象,可使用该对象来执行SQL语句并获取结果。

当有了cursor对象后,常用函数:

函数含义
execute(operate [, param])用于执行SQL语句,返回受影响的行数。 其中,参数operate为字符串类型,表示SQL语句; 参数parameters为列表类型,表示SQL语句中的参数。
fetchone()在执行查询语句时,获取查询结果集的第一行数据,返回一个元组,即(v1, v2,...)。
fetchall()在执行查询时,获取结果集的所有行,返回一个元组,即((v11, v12,...), (v21, v22,...),...)。
close()关闭cursor对象。

说明:

(1)使用execute()执行SQL语句时,SQL语句应写成字符串型;

(2)当关闭connection和cursor对象时,记得先关闭cursor游标,后关闭connection连接。

总结:

(1)当要使用cursor游标对象来执行SQL语句时,可以使用excute()方法;

(2)注意:在使用pymysql执行SQL语句时,要使用cursor对象来操作。

四、数据记录操作

1、准备数据表

通常情况下,在使用pymysql模块前,会先创建好数据库和数据表字段信息。

这样,可以更便于后期操作。

例如,使用MySQL命令完成:

(1)创建一个班级db_students数据库,并设定为utf8编码;

(2)在库中新建一个数据表,包含编号id、姓名name、性别gender、年龄age等字段;

(3)其中,字段编号id为整型、主键且自动增长;

(4)操作完成后,查看表结构,并查看表内是否有数据内容。

######################新建库和表#############################
# 创建库
create database if not exists db_students charset utf8;
# 使用库
use db_students;
# 查看表信息
show tables;
# 创建表
create table if not exists student(id int primary key auto_increment,name varchar(20),gender varchar(10),age int
) engine = InnoDB default charset utf8;
# 查看表字段
desc student;
# 查看表数据
select * from student;

总结:

(1)在操作pymysql前,请记得先创建好数据表,便于后面的程序执行。

2、插入数据

当已成功创建好了数据库和数据表,就可以使用pymysql来给表内添加数据了。使用函数:

函数含义
execute(operate [, param])用于执行SQL语句,返回受影响的行数。 其中,参数operate为字符串类型,表示SQL语句; 参数parameters为列表类型,表示SQL语句中的参数。

说明:

param参数是可选项。

例如,使用pymysql模块来完成:

(1)使用execute()向学生表中插入1条学生数据;

(2)使用DataGrip查看添加成功后的数据结果;

(3)思考:如果要插入两条数据,该怎么做呢?

# 1、导入模块
import pymysql# 2、创建连接对象
conn = pymysql.connect(host='192.168.88.100',port=3306,user='root',password='123456',database= 'db_students',charset='utf8'
)
print(conn)  # 测试一下服务器是否联通# 3、获取游标
db_cursor = conn.cursor()# 4、使用游标来执行sql
result = db_cursor.execute("insert into student(name,gender,age) values ('刘备','男',23)")
print(result) # 返回影响的行数# 5、增删改之后,一定要让操作生效,必须要提交事务,否则不生效
conn.commit()# 6、关闭游标对象;
db_cursor.close()# 7、关闭连接对象。
conn.close()

总结:

(1)当使用pymysql模块插入数据,必须使用commit()方法提交事务;

(2)注意:使用PyCharm编写程序插入数据成功后,可以到DataGrip中查看是否已成功添加数据。

3、修改数据

当数据显示有误时,就需要来修改数据内容。使用函数:

函数含义
execute(operate [, param])用于执行SQL语句,返回受影响的行数。 其中,参数operate为字符串类型,表示SQL语句; 参数parameters为列表类型,表示SQL语句中的参数。

说明:

param参数是可选项。

例如,使用pymysql模块来完成:

(1)使用execute()修改学生表中id为1的数据,并把年龄修改为19岁,姓名修改为王军;

(2)使用DataGrip查看修改成功后的数据结果;

(3)思考:能否把性别为男的所有数据,性别都修改为Male呢?
 

# 1、导入模块
import pymysql# 2、创建连接对象
conn = pymysql.connect(host='192.168.88.100',port=3306,user='root',password='123456',database= 'db_students',charset='utf8'
)
print(conn)  # 测试一下服务器是否联通# 3、获取游标
db_cursor = conn.cursor()# 4、使用游标来执行sql
result = db_cursor.execute("""update student set name = '大乔' where id = 4""")
print(result) # 返回影响的行数# 5、增删改之后,一定要让操作生效,必须要提交事务,否则不生效
conn.commit()# 6、关闭游标对象;
db_cursor.close()# 7、关闭连接对象。
conn.close()

总结:

(1)当使用pymysql模块修改数据,要使用commit()方法进行提交事务;

(2)注意:若要修改数据表的数据内容,必须先已存在该数据。

4、删除数据

当数据内容已失效时,就需要来删除数据内容。使用函数:

函数含义
execute(operate [, param])用于执行SQL语句,返回受影响的行数。 其中,参数operate为字符串类型,表示SQL语句; 参数parameters为列表类型,表示SQL语句中的参数。

说明:

param参数是可选项。

例如,使用pymysql模块来完成:

(1)使用execute()删除学生表中id为2的这条数据;

(2)使用DataGrip查看删除成功后的数据结果;

(3)思考:目前,使用execute()操作数据时,都采用硬编码方式,会存在什么问题吗?

# 1、导入模块
import pymysql# 2、创建连接对象
conn = pymysql.connect(host='192.168.88.100',port=3306,user='root',password='123456',database= 'db_students',charset='utf8'
)
print(conn)  # 测试一下服务器是否联通# 3、获取游标
db_cursor = conn.cursor()# 4、使用游标来执行sql
result = db_cursor.execute("""delete from student where name = '曹操'""")
print(result) # 返回影响的行数# 5、增删改之后,一定要让操作生效,必须要提交事务,否则不生效
conn.commit()# 6、关闭游标对象;
db_cursor.close()# 7、关闭连接对象。
conn.close()

总结:

(1)当要删除数据记录时,应该使用delete关键字;

(2)注意:使用pymysql模块删除数据时,也需要进行提交事务。

5、SQL注入

SQL注入指的是:恶意篡改或注入SQL条件。

当开发者的数据条件若被恶意篡改,那就达不到预期的查询效果。

为了了解SQL注入是怎么回事?通过一个案例来分析。

例如,使用命令来完成:

(1)给学生表tb_student中添加一些数据,查看效果;

(2)查询age=22的这条数据的所有信息;

(3)使用SQL注入方式来恶意篡改查询条件,比如在条件结尾处,添加or 1=1,并查询结果;

(4)思考:对比两次查询结果,该如何解决这类SQL注入问题呢?

# 1、导入模块
import pymysql# 2、创建连接对象
conn = pymysql.connect(host='192.168.88.100',port=3306,user='root',password='123456',database= 'db_students',charset='utf8'
)
print(conn)  # 测试一下服务器是否联通# 3、获取游标
db_cursor = conn.cursor()input_id = input('请输入你要删除的id:')  # 从键盘输入: 88 or 1=1
# 4、使用游标来执行sql                   # 发现所有数据都被删除,因为or后边的条件永远成立,条件永远为真
result = db_cursor.execute(f"""delete from student where id = {input_id}   """)
print(result) # 返回影响的行数# 5、增删改之后,一定要让操作生效,必须要提交事务,否则不生效
conn.commit()# 6、关闭游标对象;
db_cursor.close()# 7、关闭连接对象。
conn.close()

注意:当恶意篡改了SQL条件后,查询的结果可能达不到预期效果。

6、语句参数化

如果要解决SQL注入的问题,在pymysql模块中,可采用语句参数化来解决。

语句参数化是指以%s表示值,然后再传入具体的参数值进行替换。

为了更好理解语句参数化,可以把SQL语句的参数化、值,简要地理解为print()函数中的格式化符号输出:

print("xxx%s, xxx%d"%(name, age))

要使用cursor对象的函数:

函数含义
execute(operate, param)用于执行SQL语句,返回受影响的行数。 其中,参数operation为字符串类型,表示具体的SQL语句,注意,若在SQL语句中要向外传入参数值,则该参数均使用%s表示; 参数parameters为列表类型,表示SQL语句中的参数。

说明:

param参数的类型是列表list。

例如,使用pymysql模块来完成:

(1)通过键盘录入的方式输入变化的数据值;

(2)使用语句参数化和execute()给数据表添加一条数据内容;

(3)操作完成后,使用DataGrip查看添加成功后的数据结果。

# 1、导入模块
import pymysql# 2、创建连接对象
conn = pymysql.connect(host='192.168.88.100',port=3306,user='root',password='123456',database= 'db_students',charset='utf8'
)
print(conn)  # 测试一下服务器是否联通# 3、获取游标
db_cursor = conn.cursor()input_id = input('请输入你要删除的id:')  # 从键盘输入: 88 or 1=1
params = [input_id]
# 不管你从键盘输入什么都会当做普通字符串赋值给%s,id = '88 or 1=1'  -以前--> id = 88 or 1=1
sql= "delete from student where id =  %s "  
# 4、使用游标来执行sql                  
result = db_cursor.execute(sql,params)print(result) # 返回影响的行数# 5、增删改之后,一定要让操作生效,必须要提交事务,否则不生效
conn.commit()# 6、关闭游标对象;
db_cursor.close()# 7、关闭连接对象。
conn.close()
# 1、导入模块
import pymysql# 2、创建连接对象
conn = pymysql.connect(host='192.168.88.100',port=3306,user='root',password='123456',database= 'db_students',charset='utf8'
)
print(conn)  # 测试一下服务器是否联通# 3、获取游标
db_cursor = conn.cursor()param = ['张飞','男',33]
sql = 'insert into student(name,gender,age) values (%s,%s,%s)'
result = db_cursor.execute(sql, param)print(result) # 返回影响的行数# 5、增删改之后,一定要让操作生效,必须要提交事务,否则不生效
conn.commit()# 6、关闭游标对象;
db_cursor.close()# 7、关闭连接对象。
conn.close()

总结:

(1)语句参数化时,必须使用%s表示参数

(2)注意:要进行语句参数化时,使用execute()方法时需要传递两个参数。

7、查询数据

查询数据,要使用cursor对象的函数:

函数含义
execute(operate [, param])用于执行SQL语句,返回受影响的行数。 其中,参数operation为字符串类型,表示具体的SQL语句,注意,若在SQL语句中要向外传入参数值,则该参数均使用%s表示; 参数parameters为列表类型,表示SQL语句中的参数。
fetchone()在执行查询语句时,获取查询结果集的第一行数据,返回一个元组,即(v1, v2,...)。
fetchall()在执行查询时,获取结果集的所有行,返回一个元组,即((v11, v12,...), (v21, v22,...),...)。

说明:

查询的数据结果是元组类型。

例如,使用pymysql模块来完成:

(1)使用fetchone来查询一条某xx姓名的数据信息;

(2)使用fetchall()查询出所有数据信息,并遍历出详细信息。

# 1、导入模块
import pymysql# 2、创建连接对象
conn = pymysql.connect(host='192.168.88.100',port=3306,user='root',password='123456',database= 'db_students',charset='utf8'
)
print(conn)  # 测试一下服务器是否联通# 3、获取游标
db_cursor = conn.cursor()# 执行sql,进行查询
sql = 'select * from student'
db_cursor.execute(sql)# 获取查询结果,获取一行
print(db_cursor.fetchone())print('--------------------')
# 获取查询结果,获取多行,并遍历
result = db_cursor.fetchall()for row2 in result:print(row2)# 1、导入模块
import pymysql# 2、创建连接对象
conn = pymysql.connect(host='192.168.88.100',port=3306,user='root',password='123456',database= 'db_students',charset='utf8'
)
print(conn)  # 测试一下服务器是否联通# 3、获取游标
db_cursor = conn.cursor()# 执行sql,进行查询,男性,年龄大于20岁的学生信息
gender = input('请输入你要查询的性别: ')
age = input('请输入你要查询的年龄: ')params = [gender,age]
sql = 'select * from student where gender = %s and age > %s'  # %s 表示占位符
db_cursor.execute(sql,params)print('--------------------')
# 获取查询结果,获取多行,并遍历
result = db_cursor.fetchall()for row2 in result:print(row2)# 5、增删改之后,一定要让操作生效,必须要提交事务,否则不生效
conn.commit()# 6、关闭游标对象;
db_cursor.close()# 7、关闭连接对象。
conn.close()

总结:

(1)当要获取所有查询结果数据时,可以使用fetchall()方法;

(2)注意:虽然查询数据无需提交事务,但还是建议提交一下,这样可以避免与CRUD的差异化。

五、注册与登录案例

1、注册

比如,在登录某网站前,是需要进行注册用户的。那么,注册是怎么做的呢?

其实,注册用户本质上就是给用户表添加一条数据。

例如,一起来完成:

(1)新建一个班级db_users数据库,编码为utf8;

(2)在库中新建一个用户表,字段有:编号id[主键自增]、用户名username、密码password;

(3)使用键盘录入数据的形式输入用户名、密码,并用于注册一个用户;

(4)使用DataGrip查看注册成功后的用户数据结果。

import pymysqldb_conn = pymysql.connect(host="localhost",port=3306,user="root",password="123456",database="db_users",charset="utf8"
)
db_cursor = db_conn.cursor()
# 执行插入语句
in_name = input("请输入用户名:")
in_pwd = input("请输入密码:")
params = [in_name,in_pwd]
sql = "insert into tb_user(username,password) values(%s,%s)"
db_cursor.execute(sql,params)# 提交事务
db_conn.commit()
db_cursor.close()
db_conn.close()
print("数据注册已结束!~~")

总结:

(1)当要注册用户时,本质上实现的是插入数据功能;

(2)注意:使用pymysql模块操作注册功能时,记得进行语句参数化。

2、登录

当成功注册用户信息后,则可以进行登录操作了。那么,登录是怎么做的呢?

其实,登录账户本质上就是:查询用户数据,并与用户手动输入的用户名和密码进行匹配。

当匹配成功,则可以登录;反之,则登录失败。

例如,一起来完成:

(1)使用键盘录入数据的形式输入用户名、密码,并用于登录操作;

(2)当登录时,使用的数据内容则是已注册成功的用户表信息;

(3)观察注册成功后的用户数据,当已匹配成功,则表示成功登录。

import pymysqldb_conn = pymysql.connect(host="localhost",port=3306,user="root",password="123456",database="db_users",charset="utf8"
)
db_cursor = db_conn.cursor()
# 执行查询语句、匹配
sql = "select username,password from tb_user"
db_cursor.execute(sql)
query_result = db_cursor.fetchall()
print(query_result)# 匹配
in_uname = input("请输入用户名:")
in_upwd = input("请输入密码:")
# for user in query_result:
for username,password in query_result:if in_uname == username and in_upwd == password:print(f"恭喜你,{username}, 已登录成功!!")break  # 跳出
else:print("登录失败!!!")# 提交事务
db_conn.commit()
db_cursor.close()
db_conn.close()
print("数据注册已结束!~~")

总结:

(1)在Python中,如果要判断数据内容是否匹配成功可以使用if语句

(2)注意:在实际应用中,登录和注册功能可能还会涉及到用户数据加密,比如MD5加密、SHA1加密等。

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

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

相关文章

基于ANSIBLE中的YAML非标记语言Role角色扮演

YAML-YAML Ain’t Markup Language-非标记语言 语法 列表 fruits:​ - Apple​ - Orange​ - Strawberry​ - Mango 字典 martin:​ name : Martin D’vloper​ job : Developer​ skill : Elite 示例1 需求 通过YAML编写一个简单的剧本,完成web的部署&#xff0c…

【Mongodb-04】Mongodb聚合管道操作基本功能

Mongodb系列整体栏目 内容链接地址【一】Mongodb亿级数据性能测试和压测https://zhenghuisheng.blog.csdn.net/article/details/139505973【二】springboot整合Mongodb(详解)https://zhenghuisheng.blog.csdn.net/article/details/139704356【三】亿级数据从mysql迁移到mongodb…

【Springboot】新增profile环境配置应用启动失败

RT 最近接手了一个新的项目,为了不污染别人的环境,我新增了一个自己的环境配置。结果,在启动的时候总是失败,就算是反复mvn clean install也是无效。 问题现象 卡住无法进行下一步 解决思路 由于之前都是能启动的&#xff0c…

视频素材网站无水印的有哪些?热门视频素材网站分享

当我们走进视频创作的精彩世界时,一个难题常常摆在面前——那些高品质、无水印的视频素材究竟应该在哪里寻找?许多视频创作者感叹,寻找理想的视频素材难度甚至超过了寻找伴侣!但不用担心,今天我将为您介绍几个优质的视…

宝塔安装RabbitMq教程

需要放开15672端口,默认账号密码为guest/guest

浅说区间dp(下)

文章目录 环形区间dp例题[NOI1995] 石子合并题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示思路 [NOIP2006 提高组] 能量项链题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示思路 [NOIP2001 提高组] 数的划分题目描述输入格式输出格式样例 #1样例输…

车载音视频App框架设计

简介 统一播放器提供媒体播放一致性的交互和视觉体验,减少各个媒体应用和场景独自开发的重复工作量,实现媒体播放链路的一致性,减少碎片化的Bug。本文面向应用开发者介绍如何快速接入媒体播放器。 主要功能: 新设计的统一播放U…

进程空间的回收以及执行当前进程空间内的另一进程

1.进程的退出 1.exit 功能: 让进程退出,并刷新缓存区 参数: status:进程退出的状态 返回值: 缺省 exit -> 刷新缓存区 -> atexit注册的退出函数 -> _exit 2._exit 功能: 让进程退出,不刷…

代码随想录——分割等和子集(Leetcode LCR 101)

题目链接 0-1背包问题 class Solution {public boolean canPartition(int[] nums) {int[] dp new int[10000];int sum 0;// 首先求背包体积应该为nums数组总和的一半for(int i 0; i < nums.length; i){sum nums[i];}// 如果总和为奇数则不存在等和子集if(sum % 2 1)…

输出调节求解跟踪问题(二阶线性系统)

本文研究了一种基于增广系统的领导者-跟随者控制框架&#xff0c;旨在实现跟随者系统对领导者参考信号的精确跟踪。首先&#xff0c;建立了跟随者和领导者的独立状态空间方程&#xff0c;分别描述了它们的动态行为和输出关系。随后&#xff0c;通过将两者的状态空间方程结合成增…

在Linux系统安装MySQL有多简单

MySQL 是一种流行的开源关系数据库管理系统&#xff0c;广泛应用于各种类型的应用程序和服务。在安装TitanIDE​​​​​​​以后是没有MySQL服务的&#xff0c;我们需要单独安装安装MySQL。本文将介绍在 Linux 上安装 MySQL 的多种方式&#xff0c;包括离线安装、使用 Docker …

el-tree动态添加子节点的问题

如果我们需要动态往el-tree里面某一个节点添加子节点&#xff0c;追加或删除&#xff0c;我跟你讲&#xff0c;一定要显式地调用el-tree的方法&#xff0c;不然的话&#xff0c;后面调用setChecked这种方法看不到效果的。 比如el-tree绑定的data如下&#xff1a; [{id:"1…

DP(1500-1700)(刷题)

1.状态机模型&#xff1a;https://codeforces.com/contest/1984/problem/C2 记一下max与min状态转移即可&#xff0c;下面是AC代码&#xff1a; #include<bits/stdc.h> using namespace std; typedef long long ll; ll a[200010],t,n; ll dp[200010][2];//dp[i][0]表示…

掌握这些技巧,让你成为画册制作高手

在数字化的时代背景下&#xff0c;电子画册以其便捷的传播方式、丰富的视觉表现形式&#xff0c;赢得了大众的喜爱。它不仅能够在个人电脑上展现&#xff0c;还能通过智能手机、平板电脑等多种移动设备随时随地被访问和浏览。这种跨平台的支持&#xff0c;使得无论你身处何地&a…

volatile关键字解析

一、volatile介绍 volatile是Java提供的一种轻量级的同步机制&#xff0c;在并发编程中&#xff0c;它也扮演着比较重要的角色。同synchronized相比&#xff08;synchronized通常称为重量级锁&#xff09;&#xff0c;volatile更轻量级&#xff0c;相比使用synchronized所带来的…

leetcode热题100.分割等和子集(动态规划)

分割等和子集 Problem: 416. 分割等和子集 思路 我选择使用动态规划的方法来解题。我们需要判断是否可以将数组分割成两个子集&#xff0c;使得这两个子集的和相等。这个问题可以转化为在数组中找到一个子集&#xff0c;使得其和等于数组总和的一半。 解题过程 首先&#xf…

【Django】网上蛋糕商城后台-商品管理

1.商品管理功能 当管理员点击商品管理时&#xff0c;发送服务器请求 path(admin/goods_list/, viewsAdmin.goods_list), # 处理商品列表请求 def goods_list(request):try:type request.GET["type"]except:type 0try:ym request.GET["ym"]except:ym …

5大常用的回归测试工具介绍

回归测试工具介绍 以下是一些可用于创建和执行回归测试的工具。但是&#xff0c;在决定使用哪些产品之前&#xff0c;应彻底研究每种产品的要求。 Selenium Selenium 是一个开源 Web 自动化测试工具&#xff0c;用于测试网站和 Web 应用程序。它被认为是用于Web 应用程序测试的…

路径规划 | 基于DQN深度强化学习算法的路径规划(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 DQN路径规划算法 基于深度强化学习算法的路径规划 matlab2023b 栅格环境&#xff0c;走迷宫&#xff0c;可以通过窗口界面方便观察交互过程&#xff0c;代码注释详尽。 程序设计 完整源码和数据私信博主回复基于DQN深…

【Linux信号】信号的保存、信号在内核中的表示、信号集操作函数、sigprocmask、sigpending

目录 信号在内核中的表示信号阻塞的理解 sigset_t 信号集操作函数 sigprocmask sigpending sigprocmask和sigpending都是系统调用 我们先来了解一下关于信号的一些常见概念&#xff1a; 实际执行 信号的处理动作 称为信号递达。 信号从产生到递达的之间的状态称为信号未决…